breadx/futures/
wait_for_reply.rs1use super::{CheckForError, WaitForReplyRaw};
7use crate::{
8 display::{AsyncDisplay, AsyncDisplayExt, Cookie},
9 Result,
10};
11use alloc::vec::Vec;
12use core::{
13 future::Future,
14 marker::PhantomData,
15 mem,
16 pin::Pin,
17 task::{Context, Poll},
18};
19use futures_util::FutureExt;
20use x11rb_protocol::x11_utils::TryParseFd;
21
22pub struct WaitForReply<'this, Dpy: ?Sized, Reply> {
24 innards: Innards<'this, Dpy>,
25 _marker: PhantomData<Reply>,
26}
27
28enum Innards<'this, Dpy: ?Sized> {
29 Waiting(WaitForReplyRaw<'this, Dpy>),
30 Checking(CheckForError<'this, Dpy>),
31}
32
33impl<'this, Dpy: AsyncDisplay + ?Sized, Reply> WaitForReply<'this, Dpy, Reply> {
34 pub(crate) fn new(dpy: &'this mut Dpy, cookie: Cookie<Reply>) -> Self {
35 Self {
36 innards: if mem::size_of::<Reply>() == 0 {
37 Innards::Checking(dpy.check_for_error(cookie.sequence()))
38 } else {
39 Innards::Waiting(dpy.wait_for_reply_raw(cookie.sequence()))
40 },
41 _marker: PhantomData,
42 }
43 }
44
45 pub(crate) fn cannibalize(self) -> &'this mut Dpy {
46 match self.innards {
47 Innards::Waiting(innards) => innards.cannibalize(),
48 Innards::Checking(innards) => innards.cannibalize(),
49 }
50 }
51}
52
53impl<'this, Dpy: AsyncDisplay + ?Sized, Reply: TryParseFd + Unpin> Future
54 for WaitForReply<'this, Dpy, Reply>
55{
56 type Output = Result<Reply>;
57
58 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<Reply>> {
59 let this = self.get_mut();
60
61 match this.innards {
63 Innards::Waiting(ref mut wait_for_reply_raw) => {
64 match wait_for_reply_raw.poll_unpin(ctx) {
65 Poll::Ready(Ok(reply)) => Poll::Ready({
66 reply.into_reply()
68 }),
69 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
70 Poll::Pending => Poll::Pending,
71 }
72 }
73 Innards::Checking(ref mut check) => check.poll_unpin(ctx).map_ok(|()| {
74 Reply::try_parse_fd(&[], &mut Vec::new())
75 .unwrap_or_else(|_| unreachable!())
76 .0
77 }),
78 }
79 }
80}