Skip to content

Commit f657e3d

Browse files
cr feedback
1 parent c4f4acf commit f657e3d

File tree

5 files changed

+98
-39
lines changed

5 files changed

+98
-39
lines changed

src/error.rs

+57-2
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,9 @@ pub enum ErrorKind {
458458
DnsResolve { message: String },
459459

460460
/// A GridFS error occurred.
461-
#[error("{message}")]
461+
#[error("{0:?}")]
462462
#[non_exhaustive]
463-
GridFS { message: String },
463+
GridFs(GridFsErrorKind),
464464

465465
#[error("Internal error: {message}")]
466466
#[non_exhaustive]
@@ -698,6 +698,61 @@ impl WriteFailure {
698698
}
699699
}
700700

701+
/// An error that occurred during a GridFS operation.
702+
#[derive(Clone, Debug)]
703+
#[allow(missing_docs)]
704+
#[non_exhaustive]
705+
pub enum GridFsErrorKind {
706+
/// The file with the given identifier was not found.
707+
#[non_exhaustive]
708+
FileNotFound { identifier: GridFsFileIdentifier },
709+
710+
/// The file with the given revision was not found.
711+
#[non_exhaustive]
712+
RevisionNotFound { revision: i32 },
713+
714+
/// The chunk at index 'n' was missing.
715+
#[non_exhaustive]
716+
MissingChunk { n: u32 },
717+
718+
/// The chunk was the incorrect size.
719+
#[non_exhaustive]
720+
WrongSizeChunk {
721+
actual_size: u32,
722+
expected_size: u32,
723+
},
724+
725+
/// An incorrect number of chunks was present for the file.
726+
#[non_exhaustive]
727+
WrongNumberOfChunks {
728+
actual_number: u32,
729+
expected_number: u32,
730+
},
731+
}
732+
733+
/// An identifier for a file stored in a GridFS bucket.
734+
#[derive(Clone, Debug)]
735+
#[non_exhaustive]
736+
pub enum GridFsFileIdentifier {
737+
/// The name of the file. Not guaranteed to be unique.
738+
Filename(String),
739+
740+
/// The file's unique [`Bson`] ID.
741+
Id(Bson),
742+
}
743+
744+
impl From<&str> for GridFsFileIdentifier {
745+
fn from(filename: &str) -> Self {
746+
Self::Filename(filename.into())
747+
}
748+
}
749+
750+
impl From<Bson> for GridFsFileIdentifier {
751+
fn from(id: Bson) -> Self {
752+
Self::Id(id)
753+
}
754+
}
755+
701756
/// Translates ErrorKind::BulkWriteError cases to ErrorKind::WriteErrors, leaving all other errors
702757
/// untouched.
703758
pub(crate) fn convert_bulk_errors(error: Error) -> Error {

src/gridfs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct Chunk {
4343
/// collection document per stored file.
4444
#[derive(Debug, Deserialize, Serialize)]
4545
#[serde(rename_all = "camelCase")]
46+
#[non_exhaustive]
4647
pub struct FilesCollectionDocument {
4748
#[serde(rename = "_id")]
4849
pub id: Bson,

src/gridfs/download.rs

+35-33
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ use tokio_util::compat::FuturesAsyncWriteCompatExt;
44
use super::{options::GridFsDownloadByNameOptions, FilesCollectionDocument, GridFsBucket};
55
use crate::{
66
bson::{doc, Bson},
7-
error::{ErrorKind, Result},
7+
error::{ErrorKind, GridFsErrorKind, Result},
88
options::{FindOneOptions, FindOptions},
99
};
1010

1111
impl GridFsBucket {
1212
/// Downloads the contents of the stored file specified by `id` and writes
1313
/// the contents to the `destination`.
14-
pub async fn download_to_tokio_writer<T>(&self, id: Bson, destination: &mut T) -> Result<()>
14+
pub async fn download_to_tokio_writer<T>(&self, id: Bson, destination: T) -> Result<()>
1515
where
1616
T: tokio::io::AsyncWrite + std::marker::Unpin,
1717
{
@@ -23,14 +23,14 @@ impl GridFsBucket {
2323
let file = match self
2424
.inner
2525
.files
26-
.find_one(doc! { "_id": &id }, options)
26+
.find_one(doc! { "_id": id.clone() }, options)
2727
.await?
2828
{
2929
Some(fcd) => fcd,
3030
None => {
31-
return Err(ErrorKind::InvalidArgument {
32-
message: format!("couldn't find file with id {}", &id),
33-
}
31+
return Err(ErrorKind::GridFs(GridFsErrorKind::FileNotFound {
32+
identifier: id.into(),
33+
})
3434
.into());
3535
}
3636
};
@@ -40,11 +40,7 @@ impl GridFsBucket {
4040

4141
/// Downloads the contents of the stored file specified by `id` and writes
4242
/// the contents to the `destination`.
43-
pub async fn download_to_futures_0_3_writer<T>(
44-
&self,
45-
id: Bson,
46-
destination: &mut T,
47-
) -> Result<()>
43+
pub async fn download_to_futures_0_3_writer<T>(&self, id: Bson, destination: T) -> Result<()>
4844
where
4945
T: futures_util::io::AsyncWrite + std::marker::Unpin,
5046
{
@@ -59,7 +55,7 @@ impl GridFsBucket {
5955
pub async fn download_to_tokio_writer_by_name<T>(
6056
&self,
6157
filename: impl AsRef<str>,
62-
destination: &mut T,
58+
destination: T,
6359
options: impl Into<Option<GridFsDownloadByNameOptions>>,
6460
) -> Result<()>
6561
where
@@ -79,17 +75,27 @@ impl GridFsBucket {
7975
.build();
8076

8177
let file = match self
82-
.inner
83-
.files
78+
.files()
8479
.find_one(doc! { "filename": filename.as_ref() }, options)
8580
.await?
8681
{
8782
Some(fcd) => fcd,
8883
None => {
89-
return Err(ErrorKind::InvalidArgument {
90-
message: format!("couldn't find file with name {}", &filename.as_ref()),
84+
if self
85+
.files()
86+
.find_one(doc! { "filename": filename.as_ref() }, None)
87+
.await?
88+
.is_some()
89+
{
90+
return Err(
91+
ErrorKind::GridFs(GridFsErrorKind::RevisionNotFound { revision }).into(),
92+
);
93+
} else {
94+
return Err(ErrorKind::GridFs(GridFsErrorKind::FileNotFound {
95+
identifier: filename.as_ref().into(),
96+
})
97+
.into());
9198
}
92-
.into());
9399
}
94100
};
95101

@@ -104,7 +110,7 @@ impl GridFsBucket {
104110
pub async fn download_to_futures_0_3_writer_by_name<T>(
105111
&self,
106112
filename: impl AsRef<str>,
107-
destination: &mut T,
113+
destination: T,
108114
options: impl Into<Option<GridFsDownloadByNameOptions>>,
109115
) -> Result<()>
110116
where
@@ -117,7 +123,7 @@ impl GridFsBucket {
117123
async fn download_to_tokio_writer_common<T>(
118124
&self,
119125
file: FilesCollectionDocument,
120-
destination: &mut T,
126+
mut destination: T,
121127
) -> Result<()>
122128
where
123129
T: tokio::io::AsyncWrite + std::marker::Unpin,
@@ -144,22 +150,17 @@ impl GridFsBucket {
144150
while cursor.advance().await? {
145151
let chunk = cursor.deserialize_current()?;
146152
if chunk.n != n {
147-
return Err(ErrorKind::GridFS {
148-
message: format!("missing chunk {} in file", n),
149-
}
150-
.into());
153+
return Err(ErrorKind::GridFs(GridFsErrorKind::MissingChunk { n }).into());
151154
}
152155

153156
let chunk_length = chunk.data.bytes.len();
154157
let expected_length =
155158
std::cmp::min(total_bytes_expected - chunk_size * n as u64, chunk_size);
156159
if chunk_length as u64 != expected_length {
157-
return Err(ErrorKind::GridFS {
158-
message: format!(
159-
"chunk {} was expected to be {} bytes but is {} bytes",
160-
n, chunk_length, expected_length
161-
),
162-
}
160+
return Err(ErrorKind::GridFs(GridFsErrorKind::WrongSizeChunk {
161+
actual_size: chunk_length as u32,
162+
expected_size: expected_length as u32,
163+
})
163164
.into());
164165
}
165166

@@ -169,10 +170,11 @@ impl GridFsBucket {
169170

170171
let expected_n =
171172
total_bytes_expected / chunk_size + u64::from(total_bytes_expected % chunk_size != 0);
172-
if (n as u64) < expected_n {
173-
return Err(ErrorKind::GridFS {
174-
message: "missing last chunk in file".into(),
175-
}
173+
if (n as u64) != expected_n {
174+
return Err(ErrorKind::GridFs(GridFsErrorKind::WrongNumberOfChunks {
175+
actual_number: n,
176+
expected_number: expected_n as u32,
177+
})
176178
.into());
177179
}
178180

src/gridfs/options.rs

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ pub struct GridFsBucketOptions {
3838
pub struct GridFsUploadOptions {
3939
/// The number of bytes per chunk of this file. Defaults to the `chunk_size_bytes` specified
4040
/// in the [`GridFsBucketOptions`].
41-
#[serde(rename = "chunkSizeBytes")]
4241
pub chunk_size_bytes: Option<u32>,
4342

4443
/// User data for the 'metadata' field of the files collection document.

src/test/spec/unified_runner/test_runner.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,12 @@ impl TestRunner {
129129
));
130130

131131
for test_case in test_file.tests {
132-
// to run a single test, set the TEST_DESCRIPTION environment variable to the test's
133-
// description
134132
if let Ok(description) = std::env::var("TEST_DESCRIPTION") {
135-
if description != test_case.description {
133+
if !test_case
134+
.description
135+
.to_lowercase()
136+
.contains(&description.to_lowercase())
137+
{
136138
continue;
137139
}
138140
}

0 commit comments

Comments
 (0)