fidl_next_bind/future/
send.rs1use core::future::Future;
6use core::pin::Pin;
7use core::task::{Context, Poll, ready};
8
9use fidl_next_codec::EncodeError;
10use fidl_next_protocol::Transport;
11use pin_project::pin_project;
12
13use crate::Error;
14
15#[pin_project(project = SendFutureStateProj, project_replace = SendFutureStateOwn)]
16enum SendFutureState<'a, T: Transport> {
17 EncodeError(EncodeError),
18 SendRequest(#[pin] fidl_next_protocol::SendFuture<'a, T>),
19 Finished,
20}
21
22impl<'a, T: Transport> SendFutureState<'a, T> {
23 fn poll_state(
24 mut self: Pin<&mut Self>,
25 cx: &mut Context<'_>,
26 ) -> Poll<Result<(), Error<T::Error>>> {
27 match self.as_mut().project() {
28 SendFutureStateProj::EncodeError(_) => {
29 let state = self.project_replace(SendFutureState::Finished);
30 let SendFutureStateOwn::EncodeError(error) = state else {
31 unreachable!();
32 };
33 Poll::Ready(Err(Error::Encode(error)))
34 }
35 SendFutureStateProj::SendRequest(future) => match ready!(future.poll(cx)) {
36 Ok(()) => Poll::Ready(Ok(())),
37 Err(error) => Poll::Ready(Err(Error::Protocol(error))),
38 },
39 SendFutureStateProj::Finished => {
40 panic!("SendFutureState polled after completing");
41 }
42 }
43 }
44}
45
46#[must_use = "futures do nothing unless polled"]
48#[pin_project]
49pub struct SendFuture<
50 'a,
51 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
52 #[cfg(not(feature = "fuchsia"))] T: Transport,
53> {
54 #[pin]
55 state: SendFutureState<'a, T>,
56}
57
58impl<'a, T: Transport> SendFuture<'a, T> {
59 pub fn from_untyped(
61 result: Result<fidl_next_protocol::SendFuture<'a, T>, EncodeError>,
62 ) -> Self {
63 Self {
64 state: match result {
65 Err(error) => SendFutureState::EncodeError(error),
66 Ok(future) => SendFutureState::SendRequest(future),
67 },
68 }
69 }
70
71 pub fn encode(self) -> Result<EncodedSendFuture<'a, T>, Error<T::Error>> {
75 Ok(EncodedSendFuture {
76 state: match self.state {
77 SendFutureState::EncodeError(error) => return Err(Error::Encode(error)),
78 state => state,
79 },
80 })
81 }
82}
83
84impl<'a, T: Transport> Future for SendFuture<'a, T> {
85 type Output = Result<(), Error<T::Error>>;
86
87 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
88 self.project().state.poll_state(cx)
89 }
90}
91
92#[must_use = "futures do nothing unless polled"]
97#[pin_project]
98pub struct EncodedSendFuture<
99 'a,
100 #[cfg(feature = "fuchsia")] T: Transport = zx::Channel,
101 #[cfg(not(feature = "fuchsia"))] T: Transport,
102> {
103 #[pin]
104 state: SendFutureState<'a, T>,
105}
106
107impl<'a, T: Transport> Future for EncodedSendFuture<'a, T> {
108 type Output = Result<(), Error<T::Error>>;
109
110 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
111 self.project().state.poll_state(cx)
112 }
113}