I am relatively new to Rust and work on a library that works with data that is loaded by a method that is implemented by the library user. This method returns a Future (still futures 0.1 though for now). I have the following trait and an implementation for it:
// Implemented in library
#[derive(Clone, Debug)]
pub struct DataLoaderResult {
path: String,
byterange: Range<u64>,
content: Vec<u8>,
compress: String,
raw: bool,
}
pub trait DataLoader {
fn get(&self, path: String, progress: Option<bool>, tuples: Vec<(String, u64, u64)>, num: usize)
-> Pin<Box<dyn Future<Item = HashMap<String, Result<DataLoaderResult, Error>>, Error = Error>>>;
}
// Implemented by lib user
impl DataLoader for HTTPDataLoader {
fn get(&self, path: String, progress: Option<bool>, tuples: Vec<(String, u64, u64)>, num: usize)
-> Pin<Box<dyn Future<Item = HashMap<String, Result<DataLoaderResult, Error>>, Error = Error>>> {
Box::pin(HashMap::new());
}
}
// This impl is stored as a field in a struct:
pub struct CacheService<'a> {
pub data_loader: &'a dyn DataLoader,
}
The trait method returns a Future and I would like to call it in a method of CacheService
above and then call and_then()
on it, i.e.:
let load_data = self.data_loader.get(...);
load_data.and_then(|data| {
// do something
}
However, if I do this, I get this error:
error: the `and_then` method cannot be invoked on a trait object
--> /home/tom/dev/rust-test/src/lib.rs:1315:36
|
1315 | data.and_then(|remote_fragments| {
| ^^^^^^^^
|
::: /home/tom/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-0.1.31/src/future/mod.rs:529:21
|
529 | Self: Sized,
| ----- this has a `Sized` requirement
What is going on here? I would really appreciate some insight and possible solutions. It looks like that I have to use a trait object (because there are possibly different implementations of get()
, but maybe that's a misconception.