@@ -6,19 +6,43 @@ use crate::{
6
6
gridfs:: {
7
7
FilesCollectionDocument ,
8
8
GridFsBucket ,
9
+ GridFsDownloadByIdOptions ,
9
10
GridFsDownloadByNameOptions ,
10
11
GridFsDownloadStream ,
11
12
} ,
12
13
} ;
13
14
15
+ // TODO: Determine proper visibility, including parent modules.
16
+ pub struct DownloadRange ( pub Option < u64 > , pub Option < u64 > ) ;
17
+
18
+ fn create_download_range ( start : Option < u64 > , end : Option < u64 > ) -> Result < DownloadRange > {
19
+ match ( start, end) {
20
+ ( Some ( start) , Some ( end) ) => {
21
+ if start <= end {
22
+ Ok ( DownloadRange ( Some ( start) , Some ( end) ) )
23
+ } else {
24
+ Err (
25
+ ErrorKind :: GridFs ( GridFsErrorKind :: InvalidPartialDownloadRange { start, end } )
26
+ . into ( ) ,
27
+ )
28
+ }
29
+ }
30
+ _ => Ok ( DownloadRange ( start, end) ) ,
31
+ }
32
+ }
33
+
14
34
impl GridFsBucket {
15
35
/// Opens and returns a [`GridFsDownloadStream`] from which the application can read
16
36
/// the contents of the stored file specified by `id`.
17
37
///
18
38
/// `await` will return d[`Result<GridFsDownloadStream>`].
19
39
#[ deeplink]
20
40
pub fn open_download_stream ( & self , id : Bson ) -> OpenDownloadStream {
21
- OpenDownloadStream { bucket : self , id }
41
+ OpenDownloadStream {
42
+ bucket : self ,
43
+ id,
44
+ options : None ,
45
+ }
22
46
}
23
47
24
48
/// Opens and returns a [`GridFsDownloadStream`] from which the application can read
@@ -129,15 +153,28 @@ impl crate::sync::gridfs::GridFsBucket {
129
153
pub struct OpenDownloadStream < ' a > {
130
154
bucket : & ' a GridFsBucket ,
131
155
id : Bson ,
156
+ options : Option < GridFsDownloadByIdOptions > ,
157
+ }
158
+
159
+ impl < ' a > OpenDownloadStream < ' a > {
160
+ option_setters ! { options: GridFsDownloadByIdOptions ;
161
+ start: u64 ,
162
+ end: u64 ,
163
+ }
132
164
}
133
165
134
166
#[ action_impl( sync = crate :: sync:: gridfs:: GridFsDownloadStream ) ]
135
167
impl < ' a > Action for OpenDownloadStream < ' a > {
136
168
type Future = OpenDownloadStreamFuture ;
137
169
138
170
async fn execute ( self ) -> Result < GridFsDownloadStream > {
171
+ let range = create_download_range (
172
+ self . options . as_ref ( ) . and_then ( |options| options. start ) ,
173
+ self . options . as_ref ( ) . and_then ( |options| options. end ) ,
174
+ ) ?;
175
+
139
176
let file = self . bucket . find_file_by_id ( & self . id ) . await ?;
140
- GridFsDownloadStream :: new ( file, self . bucket . chunks ( ) ) . await
177
+ GridFsDownloadStream :: new ( file, self . bucket . chunks ( ) , range ) . await
141
178
}
142
179
}
143
180
@@ -154,6 +191,8 @@ pub struct OpenDownloadStreamByName<'a> {
154
191
impl < ' a > OpenDownloadStreamByName < ' a > {
155
192
option_setters ! { options: GridFsDownloadByNameOptions ;
156
193
revision: i32 ,
194
+ start: u64 ,
195
+ end: u64 ,
157
196
}
158
197
}
159
198
@@ -162,10 +201,15 @@ impl<'a> Action for OpenDownloadStreamByName<'a> {
162
201
type Future = OpenDownloadStreamByNameFuture ;
163
202
164
203
async fn execute ( self ) -> Result < GridFsDownloadStream > {
204
+ let range = create_download_range (
205
+ self . options . as_ref ( ) . and_then ( |options| options. start ) ,
206
+ self . options . as_ref ( ) . and_then ( |options| options. end ) ,
207
+ ) ?;
208
+
165
209
let file = self
166
210
. bucket
167
211
. find_file_by_name ( & self . filename , self . options )
168
212
. await ?;
169
- GridFsDownloadStream :: new ( file, self . bucket . chunks ( ) ) . await
213
+ GridFsDownloadStream :: new ( file, self . bucket . chunks ( ) , range ) . await
170
214
}
171
215
}
0 commit comments