async_http_codec/internal/
io_future.rs

1use std::future::Future;
2use std::io;
3use std::marker::PhantomData;
4use std::pin::Pin;
5use std::task::{Context, Poll};
6
7pub trait IoFutureState<IO: Sized + Unpin>: Sized + Unpin {
8    fn poll(&mut self, cx: &mut Context<'_>, io: &mut IO) -> Poll<io::Result<()>>;
9    fn into_future(self, io: IO) -> IoFuture<Self, IO> {
10        IoFuture::new(self, io)
11    }
12}
13
14pub struct IoFuture<S: IoFutureState<IO>, IO: Sized + Unpin>(Option<(S, IO)>);
15
16impl<S: IoFutureState<IO>, IO: Unpin> IoFuture<S, IO> {
17    pub fn new(state: S, io: IO) -> Self {
18        IoFuture(Some((state, io)))
19    }
20    pub fn checkpoint(self) -> (S, IO) {
21        self.0.unwrap()
22    }
23}
24
25impl<S: IoFutureState<IO>, IO: Unpin> Future for IoFuture<S, IO> {
26    type Output = io::Result<IO>;
27
28    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
29        let (mut state, mut io) = self.0.take().unwrap();
30        let p = state.poll(cx, &mut io);
31        self.0 = Some((state, io));
32        p.map(|r| r.map(|()| self.0.take().unwrap().1))
33    }
34}
35
36pub trait IoFutureWithOutputState<IO: Sized + Unpin, O>: Sized + Unpin {
37    fn poll(&mut self, cx: &mut Context<'_>, io: &mut IO) -> Poll<io::Result<O>>;
38    fn into_future(self, io: IO) -> IoFutureWithOutput<Self, IO, O> {
39        IoFutureWithOutput::new(self, io)
40    }
41}
42
43pub struct IoFutureWithOutput<S: IoFutureWithOutputState<IO, O>, IO: Sized + Unpin, O: 'static>(
44    Option<(S, IO, PhantomData<&'static O>)>,
45);
46
47impl<S: IoFutureWithOutputState<IO, O>, IO: Unpin, O> IoFutureWithOutput<S, IO, O> {
48    pub fn new(state: S, io: IO) -> Self {
49        IoFutureWithOutput(Some((state, io, PhantomData::default())))
50    }
51    pub fn checkpoint(self) -> (S, IO) {
52        let (state, io, _) = self.0.unwrap();
53        (state, io)
54    }
55}
56
57impl<S: IoFutureWithOutputState<IO, O>, IO: Unpin, O> Future for IoFutureWithOutput<S, IO, O> {
58    type Output = io::Result<(IO, O)>;
59
60    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
61        let (mut state, mut io, _) = self.0.take().unwrap();
62        let p = state.poll(cx, &mut io);
63        self.0 = Some((state, io, PhantomData::default()));
64        p.map(|r| r.map(|o| (self.0.take().unwrap().1, o)))
65    }
66}