gstreamer/
promise_futures.rs1use std::{
4 ops::Deref,
5 pin::Pin,
6 task::{Context, Poll},
7};
8
9use crate::promise::{Promise, PromiseError};
10use crate::{PromiseResult, StructureRef};
11
12#[derive(Debug)]
13pub struct PromiseFuture(
14 pub(crate) Promise,
15 pub(crate) futures_channel::oneshot::Receiver<()>,
16);
17
18pub struct PromiseReply(Promise);
19
20impl std::future::Future for PromiseFuture {
21 type Output = Result<Option<PromiseReply>, PromiseError>;
22
23 fn poll(mut self: Pin<&mut Self>, context: &mut Context) -> Poll<Self::Output> {
24 match Pin::new(&mut self.1).poll(context) {
25 Poll::Ready(Err(_)) => panic!("Sender dropped before callback was called"),
26 Poll::Ready(Ok(())) => {
27 let res = match self.0.wait() {
28 PromiseResult::Replied => {
29 if self.0.get_reply().is_none() {
30 Ok(None)
31 } else {
32 Ok(Some(PromiseReply(self.0.clone())))
33 }
34 }
35 PromiseResult::Interrupted => Err(PromiseError::Interrupted),
36 PromiseResult::Expired => Err(PromiseError::Expired),
37 PromiseResult::Pending => {
38 panic!("Promise resolved but returned Pending");
39 }
40 err => Err(PromiseError::Other(err)),
41 };
42 Poll::Ready(res)
43 }
44 Poll::Pending => Poll::Pending,
45 }
46 }
47}
48
49impl futures_core::future::FusedFuture for PromiseFuture {
50 fn is_terminated(&self) -> bool {
51 self.1.is_terminated()
52 }
53}
54
55impl Deref for PromiseReply {
56 type Target = StructureRef;
57
58 #[inline]
59 fn deref(&self) -> &StructureRef {
60 self.0.get_reply().expect("Promise without reply")
61 }
62}
63
64impl std::fmt::Debug for PromiseReply {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 let mut debug = f.debug_tuple("PromiseReply");
67
68 match self.0.get_reply() {
69 Some(reply) => debug.field(reply),
70 None => debug.field(&"<no reply>"),
71 }
72 .finish()
73 }
74}