Example with rusoto
I am in creating ftp server with rusto.
get_object() function of rusto returns content body as ByteStream, so i want to return it as stream in get() function.
The function returns impl trait, but StorageBackend requires associate type File, so I can't these types be mached.
Can I get several examples or hints?
Thanks ;D
Thanks for your interest in firetrap!
It's not entirely clear to me what you're trying to do, but I'll try to help anyway.
If you're interested in writing your own StorageBackend, you can do this by using ByteStream directly as the associated type.
If you want to use the existing Filesystem backend, you could probably wrap around the tokio::fs::File that it uses, and create a ByteStream from it.
Does this help you achieve what you want?
Thank you for reply!
If you're interested in writing your own StorageBackend, you can do this by using ByteStream directly as the associated type.
We can't specify ByteStream to File association type because Byte Stream have not implemented AsyncRead.
We can't specify
ByteStreamtoFileassociation type because Byte Stream have not implementedAsyncRead.
Hmm, to be honest I'm not sure what the best approach is then. The way the StorageBackend is used now, it really needs AsyncRead (by design, or the threads could block). Perhaps you could somehow write an Async wrapper around the sync Bytestream, but I'm not really sure how I would go around doing that. Perhaps you could look at some examples from how the standard library implements Async types on top of Sync types?
My example is here.
fn get<P: AsRef<Path>>(
&self,
path: P,
) -> Box<Future<Item = Self::File, Error = Self::Error> + Send> {
let client = Arc::clone(&self.client);
let bucket = "xxxx";
let future = future::result(self.key(path))
.and_then(move |key| {
client
.get_object(rusoto_s3::GetObjectRequest {
bucket: bucket.into(),
key: key,
..Default::default()
})
.map_err(|_| ErrorKind::Unknown)
})
.and_then(|object| {
let body = object
.body
.unwrap_or_else(|| rusoto_core::ByteStream::from(vec![]));
tokio::codec::FramedRead::new(
body.into_async_read(),
tokio::codec::BytesCodec::new(),
)
.concat2()
.map_err(|_| ErrorKind::Unknown)
})
.map(|body| std::io::Cursor::new(body.to_vec()));
Box::new(future)
}
I convert into std::io::Cursor from ByteStream because Cursor have implimented AsyncRead.
ByteStream -> tokio::codec::FramedRead -> BytesMut -> Vec<u8> -> Cursor.
But we will lost advantage async programing when we convert into BytesMut.