@@ -5,10 +5,11 @@ use std::io::Read;
5
5
use std:: ops:: Range ;
6
6
use std:: sync:: Arc ;
7
7
8
+ use async_trait:: async_trait;
8
9
use byteorder:: { BigEndian , LittleEndian , ReadBytesExt } ;
9
10
use bytes:: buf:: Reader ;
10
11
use bytes:: { Buf , Bytes } ;
11
- use futures:: future:: { BoxFuture , FutureExt , TryFutureExt } ;
12
+ use futures:: future:: TryFutureExt ;
12
13
#[ cfg( feature = "object_store" ) ]
13
14
use object_store:: ObjectStore ;
14
15
@@ -30,41 +31,36 @@ use crate::error::{AsyncTiffError, AsyncTiffResult};
30
31
/// [`ObjectStore`]: object_store::ObjectStore
31
32
///
32
33
/// [`tokio::fs::File`]: https://docs.rs/tokio/latest/tokio/fs/struct.File.html
34
+ #[ cfg_attr( target_arch = "wasm32" , async_trait( ?Send ) ) ]
35
+ #[ cfg_attr( not( target_arch = "wasm32" ) , async_trait) ]
33
36
pub trait AsyncFileReader : Debug + Send + Sync {
34
37
/// Retrieve the bytes in `range`
35
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > ;
38
+ async fn get_bytes ( & self , range : Range < u64 > ) -> AsyncTiffResult < Bytes > ;
36
39
37
40
/// Retrieve multiple byte ranges. The default implementation will call `get_bytes`
38
41
/// sequentially
39
- fn get_byte_ranges (
40
- & self ,
41
- ranges : Vec < Range < u64 > > ,
42
- ) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > > {
43
- async move {
44
- let mut result = Vec :: with_capacity ( ranges. len ( ) ) ;
45
-
46
- for range in ranges. into_iter ( ) {
47
- let data = self . get_bytes ( range) . await ?;
48
- result. push ( data) ;
49
- }
42
+ async fn get_byte_ranges ( & self , ranges : Vec < Range < u64 > > ) -> AsyncTiffResult < Vec < Bytes > > {
43
+ let mut result = Vec :: with_capacity ( ranges. len ( ) ) ;
50
44
51
- Ok ( result)
45
+ for range in ranges. into_iter ( ) {
46
+ let data = self . get_bytes ( range) . await ?;
47
+ result. push ( data) ;
52
48
}
53
- . boxed ( )
49
+
50
+ Ok ( result)
54
51
}
55
52
}
56
53
57
54
/// This allows Box<dyn AsyncFileReader + '_> to be used as an AsyncFileReader,
58
- impl AsyncFileReader for Box < dyn AsyncFileReader + ' _ > {
59
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
60
- self . as_ref ( ) . get_bytes ( range)
55
+ #[ cfg_attr( target_arch = "wasm32" , async_trait( ?Send ) ) ]
56
+ #[ cfg_attr( not( target_arch = "wasm32" ) , async_trait) ]
57
+ impl AsyncFileReader for Box < dyn AsyncFileReader > {
58
+ async fn get_bytes ( & self , range : Range < u64 > ) -> AsyncTiffResult < Bytes > {
59
+ self . get_bytes ( range) . await
61
60
}
62
61
63
- fn get_byte_ranges (
64
- & self ,
65
- ranges : Vec < Range < u64 > > ,
66
- ) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > > {
67
- self . as_ref ( ) . get_byte_ranges ( ranges)
62
+ async fn get_byte_ranges ( & self , ranges : Vec < Range < u64 > > ) -> AsyncTiffResult < Vec < Bytes > > {
63
+ self . get_byte_ranges ( ranges) . await
68
64
}
69
65
}
70
66
@@ -108,30 +104,29 @@ impl ObjectReader {
108
104
}
109
105
}
110
106
#[ cfg( feature = "object_store" ) ]
107
+ #[ cfg_attr( target_arch = "wasm32" , async_trait( ?Send ) ) ]
108
+ #[ cfg_attr( not( target_arch = "wasm32" ) , async_trait) ]
111
109
impl AsyncFileReader for ObjectReader {
112
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
110
+ async fn get_bytes ( & self , range : Range < u64 > ) -> AsyncTiffResult < Bytes > {
113
111
let range = range. start as _ ..range. end as _ ;
114
112
self . store
115
113
. get_range ( & self . path , range)
116
114
. map_err ( |e| e. into ( ) )
117
- . boxed ( )
115
+ . await
118
116
}
119
117
120
- fn get_byte_ranges ( & self , ranges : Vec < Range < u64 > > ) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > >
118
+ async fn get_byte_ranges ( & self , ranges : Vec < Range < u64 > > ) -> AsyncTiffResult < Vec < Bytes > >
121
119
where
122
120
Self : Send ,
123
121
{
124
122
let ranges = ranges
125
123
. into_iter ( )
126
124
. map ( |r| r. start as _ ..r. end as _ )
127
125
. collect :: < Vec < _ > > ( ) ;
128
- async move {
129
- self . store
130
- . get_ranges ( & self . path , & ranges)
131
- . await
132
- . map_err ( |e| e. into ( ) )
133
- }
134
- . boxed ( )
126
+ self . store
127
+ . get_ranges ( & self . path , & ranges)
128
+ . await
129
+ . map_err ( |e| e. into ( ) )
135
130
}
136
131
}
137
132
@@ -150,18 +145,20 @@ impl ReqwestReader {
150
145
}
151
146
}
152
147
#[ cfg( feature = "reqwest" ) ]
148
+ #[ cfg_attr( target_arch = "wasm32" , async_trait( ?Send ) ) ]
149
+ #[ cfg_attr( not( target_arch = "wasm32" ) , async_trait) ]
153
150
impl AsyncFileReader for ReqwestReader {
154
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
151
+ async fn get_bytes ( & self , range : Range < u64 > ) -> AsyncTiffResult < Bytes > {
152
+ // }
153
+ // fn get_bytes<'async_trait>(&'async_trait self, range: Range<u64>) -> BoxFuture<'async_trait, AsyncTiffResult<Bytes>>
154
+ // {
155
155
let url = self . url . clone ( ) ;
156
156
let client = self . client . clone ( ) ;
157
157
// HTTP range is inclusive, so we need to subtract 1 from the end
158
158
let range = format ! ( "bytes={}-{}" , range. start, range. end - 1 ) ;
159
- async move {
160
- let response = client. get ( url) . header ( "Range" , range) . send ( ) . await ?;
161
- let bytes = response. bytes ( ) . await ?;
162
- Ok ( bytes)
163
- }
164
- . boxed ( )
159
+ let response = client. get ( url) . header ( "Range" , range) . send ( ) . await ?;
160
+ let bytes = response. bytes ( ) . await ?;
161
+ Ok ( bytes)
165
162
}
166
163
}
167
164
@@ -180,29 +177,31 @@ impl PrefetchReader {
180
177
}
181
178
}
182
179
180
+ #[ cfg_attr( target_arch = "wasm32" , async_trait( ?Send ) ) ]
181
+ #[ cfg_attr( not( target_arch = "wasm32" ) , async_trait) ]
183
182
impl AsyncFileReader for PrefetchReader {
184
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
183
+ async fn get_bytes ( & self , range : Range < u64 > ) -> AsyncTiffResult < Bytes > {
185
184
if range. start < self . buffer . len ( ) as _ {
186
185
if range. end < self . buffer . len ( ) as _ {
187
186
let usize_range = range. start as usize ..range. end as usize ;
188
187
let result = self . buffer . slice ( usize_range) ;
189
- async { Ok ( result) } . boxed ( )
188
+ Ok ( result)
190
189
} else {
191
190
// TODO: reuse partial internal buffer
192
- self . reader . get_bytes ( range)
191
+ self . reader . get_bytes ( range) . await
193
192
}
194
193
} else {
195
- self . reader . get_bytes ( range)
194
+ self . reader . get_bytes ( range) . await
196
195
}
197
196
}
198
197
199
- fn get_byte_ranges ( & self , ranges : Vec < Range < u64 > > ) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > >
198
+ async fn get_byte_ranges ( & self , ranges : Vec < Range < u64 > > ) -> AsyncTiffResult < Vec < Bytes > >
200
199
where
201
200
Self : Send ,
202
201
{
203
202
// In practice, get_byte_ranges is only used for fetching tiles, which are unlikely to
204
203
// overlap a metadata prefetch.
205
- self . reader . get_byte_ranges ( ranges)
204
+ self . reader . get_byte_ranges ( ranges) . await
206
205
}
207
206
}
208
207
0 commit comments