Skip to content

Commit 2cd95c9

Browse files
committed
updated AsyncFileReader trait and impls to not have Send futures in wasm
1 parent 8476f2c commit 2cd95c9

File tree

2 files changed

+46
-46
lines changed

2 files changed

+46
-46
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ description = "Low-level asynchronous TIFF reader."
99
readme = "README.md"
1010

1111
[dependencies]
12+
async-trait = "0.1.88"
1213
byteorder = "1"
1314
bytes = "1.7.0"
1415
flate2 = "1.0.20"

src/reader.rs

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use std::io::Read;
55
use std::ops::Range;
66
use std::sync::Arc;
77

8+
use async_trait::async_trait;
89
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
910
use bytes::buf::Reader;
1011
use bytes::{Buf, Bytes};
11-
use futures::future::{BoxFuture, FutureExt, TryFutureExt};
12+
use futures::future::TryFutureExt;
1213
#[cfg(feature = "object_store")]
1314
use object_store::ObjectStore;
1415

@@ -30,41 +31,36 @@ use crate::error::{AsyncTiffError, AsyncTiffResult};
3031
/// [`ObjectStore`]: object_store::ObjectStore
3132
///
3233
/// [`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)]
3336
pub trait AsyncFileReader: Debug + Send + Sync {
3437
/// 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>;
3639

3740
/// Retrieve multiple byte ranges. The default implementation will call `get_bytes`
3841
/// 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());
5044

51-
Ok(result)
45+
for range in ranges.into_iter() {
46+
let data = self.get_bytes(range).await?;
47+
result.push(data);
5248
}
53-
.boxed()
49+
50+
Ok(result)
5451
}
5552
}
5653

5754
/// 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
6160
}
6261

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
6864
}
6965
}
7066

@@ -108,30 +104,29 @@ impl ObjectReader {
108104
}
109105
}
110106
#[cfg(feature = "object_store")]
107+
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
108+
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
111109
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> {
113111
let range = range.start as _..range.end as _;
114112
self.store
115113
.get_range(&self.path, range)
116114
.map_err(|e| e.into())
117-
.boxed()
115+
.await
118116
}
119117

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>>
121119
where
122120
Self: Send,
123121
{
124122
let ranges = ranges
125123
.into_iter()
126124
.map(|r| r.start as _..r.end as _)
127125
.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())
135130
}
136131
}
137132

@@ -150,18 +145,20 @@ impl ReqwestReader {
150145
}
151146
}
152147
#[cfg(feature = "reqwest")]
148+
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
149+
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
153150
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+
// {
155155
let url = self.url.clone();
156156
let client = self.client.clone();
157157
// HTTP range is inclusive, so we need to subtract 1 from the end
158158
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)
165162
}
166163
}
167164

@@ -180,29 +177,31 @@ impl PrefetchReader {
180177
}
181178
}
182179

180+
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
181+
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
183182
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> {
185184
if range.start < self.buffer.len() as _ {
186185
if range.end < self.buffer.len() as _ {
187186
let usize_range = range.start as usize..range.end as usize;
188187
let result = self.buffer.slice(usize_range);
189-
async { Ok(result) }.boxed()
188+
Ok(result)
190189
} else {
191190
// TODO: reuse partial internal buffer
192-
self.reader.get_bytes(range)
191+
self.reader.get_bytes(range).await
193192
}
194193
} else {
195-
self.reader.get_bytes(range)
194+
self.reader.get_bytes(range).await
196195
}
197196
}
198197

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>>
200199
where
201200
Self: Send,
202201
{
203202
// In practice, get_byte_ranges is only used for fetching tiles, which are unlikely to
204203
// overlap a metadata prefetch.
205-
self.reader.get_byte_ranges(ranges)
204+
self.reader.get_byte_ranges(ranges).await
206205
}
207206
}
208207

0 commit comments

Comments
 (0)