1use std::future::Future;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4
5use tokio_stream::wrappers::UnboundedReceiverStream;
6use tokio_util::sync::CancellationToken;
7
8use crate::error::{FileEngineError, Result};
9use crate::progress::Progress;
10
11pub struct Handle<T> {
18 pub(crate) join: tokio::task::JoinHandle<Result<T>>,
19 pub(crate) progress_rx: UnboundedReceiverStream<Progress>,
20 pub(crate) cancel_token: CancellationToken,
21}
22
23impl<T> Handle<T> {
24 pub fn progress(&mut self) -> &mut UnboundedReceiverStream<Progress> {
25 &mut self.progress_rx
26 }
27
28 pub fn cancel(&self) {
29 self.cancel_token.cancel();
30 }
31}
32
33impl<T> Future for Handle<T> {
34 type Output = Result<T>;
35
36 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
37 let this = self.get_mut();
38 match Pin::new(&mut this.join).poll(cx) {
39 Poll::Ready(Ok(result)) => Poll::Ready(result),
40 Poll::Ready(Err(join_err)) => Poll::Ready(Err(FileEngineError::Io {
41 path: Default::default(),
42 source: std::io::Error::other(join_err),
43 })),
44 Poll::Pending => Poll::Pending,
45 }
46 }
47}