async_http_codec/internal/
io_future.rs1use 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}