Hi,
Could someone help in understanding what do I have to pin for this code to compile?
I am not sure pin<boxing< a method makes sense (the compilers' suggestion).
use futures::{
io::{AsyncRead},
Future, FutureExt,
};
use std::io::Result;
/// Implements `AsyncRead + AsyncSeek` for a non-blocking function that reads ranges of bytes.
pub struct RangedStreamer<F: Future> {
pos: u64,
length: u64, // total size
buffer: Vec<u8>, // a ring
offset: usize, // offset in the ring: buffer[:offset] have been read
range_fn: Box<dyn Fn(usize, &mut [u8]) -> F>,
}
impl<F: Future> RangedStreamer<F> {
pub fn new(
length: usize,
range_fn: Box<dyn Fn(usize, &mut [u8]) -> F>,
mut buffer: Vec<u8>,
) -> Self {
let length = length as u64;
buffer.clear();
Self {
pos: 0,
range_fn,
length,
buffer,
offset: 0,
}
}
async fn read_more(&mut self, to_consume: usize) -> Result<()> {
todo!()
}
}
impl<F: Future> AsyncRead for RangedStreamer<F> {
fn poll_read(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &mut [u8],
) -> std::task::Poll<Result<usize>> {
let to_consume = buf.len();
match self.read_more(to_consume).poll_unpin(cx) {
std::task::Poll::Ready(x) => {
std::task::Poll::Ready(x.map(|_| {
// copy from the internal buffer.
buf[..to_consume]
.copy_from_slice(&self.buffer[self.offset..self.offset + to_consume]);
// and offset
self.offset += to_consume;
to_consume
}))
}
std::task::Poll::Pending => std::task::Poll::Pending,
}
}
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0277]: `from_generator::GenFuture<[static generator@src/lib.rs:35:68: 37:6 {}]>` cannot be unpinned
--> src/lib.rs:47:42
|
35 | async fn read_more(&mut self, to_consume: usize) -> Result<()> {
| ---------- within this `impl futures::Future`
...
47 | match self.read_more(to_consume).poll_unpin(cx) {
| ^^^^^^^^^^ within `impl futures::Future`, the trait `Unpin` is not implemented for `from_generator::GenFuture<[static generator@src/lib.rs:35:68: 37:6 {}]>`
|
= note: consider using `Box::pin`
= note: required because it appears within the type `impl futures::Future`
= note: required because it appears within the type `impl futures::Future`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`
To learn more, run the command again with --verbose.