@@ -12,14 +12,13 @@ use std::{
12
12
} ;
13
13
14
14
use serde:: { Deserialize , Serialize } ;
15
- use tokio :: io :: ReadBuf ;
15
+ use serde_with :: skip_serializing_none ;
16
16
17
17
use crate :: {
18
18
bson:: { doc, oid:: ObjectId , Bson , DateTime , Document , RawBinaryRef } ,
19
- concern:: { ReadConcern , WriteConcern } ,
20
19
cursor:: Cursor ,
21
20
error:: { ErrorKind , GridFsErrorKind , GridFsFileIdentifier , Result } ,
22
- options:: { CollectionOptions , FindOptions , SelectionCriteria } ,
21
+ options:: { CollectionOptions , FindOptions , ReadConcern , SelectionCriteria , WriteConcern } ,
23
22
Collection ,
24
23
Database ,
25
24
} ;
@@ -42,8 +41,9 @@ struct Chunk<'a> {
42
41
43
42
/// A collection in which information about stored files is stored. There will be one files
44
43
/// collection document per stored file.
45
- #[ derive( Debug , Deserialize , Serialize ) ]
44
+ #[ derive( Clone , Debug , Deserialize , Serialize ) ]
46
45
#[ serde( rename_all = "camelCase" ) ]
46
+ #[ skip_serializing_none]
47
47
#[ non_exhaustive]
48
48
pub struct FilesCollectionDocument {
49
49
#[ serde( rename = "_id" ) ]
@@ -52,12 +52,39 @@ pub struct FilesCollectionDocument {
52
52
pub chunk_size : u32 ,
53
53
pub upload_date : DateTime ,
54
54
pub filename : Option < String > ,
55
- #[ serde( skip_serializing_if = "Option::is_none" ) ]
56
55
pub metadata : Option < Document > ,
57
56
}
58
57
58
+ impl FilesCollectionDocument {
59
+ /// Returns the total number of chunks expected to be in the file.
60
+ fn n ( & self ) -> u32 {
61
+ Self :: n_from_vals ( self . length , self . chunk_size )
62
+ }
63
+
64
+ fn n_from_vals ( length : u64 , chunk_size : u32 ) -> u32 {
65
+ let chunk_size = chunk_size as u64 ;
66
+ let n = length / chunk_size + u64:: from ( length % chunk_size != 0 ) ;
67
+ n as u32
68
+ }
69
+
70
+ /// Returns the expected length of a chunk given its index.
71
+ fn expected_chunk_length ( & self , n : u32 ) -> u32 {
72
+ Self :: expected_chunk_length_from_vals ( self . length , self . chunk_size , n)
73
+ }
74
+
75
+ fn expected_chunk_length_from_vals ( length : u64 , chunk_size : u32 , n : u32 ) -> u32 {
76
+ let remainder = length % ( chunk_size as u64 ) ;
77
+ if n == Self :: n_from_vals ( length, chunk_size) - 1 && remainder != 0 {
78
+ remainder as u32
79
+ } else {
80
+ chunk_size
81
+ }
82
+ }
83
+ }
84
+
59
85
#[ derive( Debug ) ]
60
86
struct GridFsBucketInner {
87
+ db : Database ,
61
88
options : GridFsBucketOptions ,
62
89
files : Collection < FilesCollectionDocument > ,
63
90
chunks : Collection < Chunk < ' static > > ,
@@ -134,27 +161,6 @@ impl futures_util::AsyncWrite for GridFsUploadStream {
134
161
}
135
162
}
136
163
137
- pub struct GridFsDownloadStream {
138
- files_id : Bson ,
139
- }
140
-
141
- impl GridFsDownloadStream {
142
- /// Gets the file `id` for the stream.
143
- pub fn files_id ( & self ) -> & Bson {
144
- & self . files_id
145
- }
146
- }
147
-
148
- impl tokio:: io:: AsyncRead for GridFsDownloadStream {
149
- fn poll_read (
150
- self : Pin < & mut Self > ,
151
- cx : & mut Context < ' _ > ,
152
- buf : & mut ReadBuf < ' _ > ,
153
- ) -> Poll < tokio:: io:: Result < ( ) > > {
154
- todo ! ( )
155
- }
156
- }
157
-
158
164
impl GridFsBucket {
159
165
pub ( crate ) fn new ( db : Database , mut options : GridFsBucketOptions ) -> GridFsBucket {
160
166
if options. read_concern . is_none ( ) {
@@ -188,6 +194,7 @@ impl GridFsBucket {
188
194
189
195
GridFsBucket {
190
196
inner : Arc :: new ( GridFsBucketInner {
197
+ db : db. clone ( ) ,
191
198
options,
192
199
files,
193
200
chunks,
@@ -230,7 +237,7 @@ impl GridFsBucket {
230
237
}
231
238
232
239
/// Gets a handle to the chunks collection for the [`GridFsBucket`].
233
- fn chunks ( & self ) -> & Collection < Chunk > {
240
+ fn chunks ( & self ) -> & Collection < Chunk < ' static > > {
234
241
& self . inner . chunks
235
242
}
236
243
@@ -260,23 +267,6 @@ impl GridFsBucket {
260
267
. await
261
268
}
262
269
263
- /// Opens and returns a [`GridFsDownloadStream`] from which the application can read
264
- /// the contents of the stored file specified by `id`.
265
- pub async fn open_download_stream ( & self , id : Bson ) -> Result < GridFsDownloadStream > {
266
- todo ! ( )
267
- }
268
-
269
- /// Opens and returns a [`GridFsDownloadStream`] from which the application can read
270
- /// the contents of the stored file specified by `filename` and the revision
271
- /// in `options`.
272
- pub async fn open_download_stream_by_name (
273
- & self ,
274
- filename : String ,
275
- options : impl Into < Option < GridFsDownloadByNameOptions > > ,
276
- ) -> Result < GridFsDownloadStream > {
277
- todo ! ( )
278
- }
279
-
280
270
/// Deletes the [`FilesCollectionDocument`] with the given `id `and its associated chunks from
281
271
/// this bucket.
282
272
pub async fn delete ( & self , id : Bson ) -> Result < ( ) > {
0 commit comments