penumbra_sdk_proto/state/
future.rs1use std::{
2 future::Future,
3 pin::Pin,
4 task::{Context, Poll},
5};
6
7use anyhow::{Context as _, Result};
8use pin_project::pin_project;
9use prost::Message;
10
11use crate::DomainType;
12
13#[pin_project]
15pub struct ProtoFuture<P, F> {
16 #[pin]
17 pub(super) inner: F,
18 pub(super) _marker: std::marker::PhantomData<P>,
19}
20
21#[pin_project]
23pub struct DomainFuture<D, F> {
24 #[pin]
25 pub(super) inner: F,
26 pub(super) _marker: std::marker::PhantomData<D>,
27}
28
29impl<F, P> Future for ProtoFuture<P, F>
30where
31 F: Future<Output = Result<Option<Vec<u8>>>>,
32 P: Message + Default,
33{
34 type Output = Result<Option<P>>;
35 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
36 let this = self.project();
37 match this.inner.poll(cx) {
38 Poll::Ready(Ok(Some(bytes))) => {
39 let v = P::decode(&*bytes).context("could not decode proto from bytes")?;
40 Poll::Ready(Ok(Some(v)))
41 }
42 Poll::Ready(Ok(None)) => Poll::Ready(Ok(None)),
43 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
44 Poll::Pending => Poll::Pending,
45 }
46 }
47}
48
49impl<D, F> Future for DomainFuture<D, F>
50where
51 F: Future<Output = Result<Option<Vec<u8>>>>,
52 D: DomainType,
53 anyhow::Error: From<<D as TryFrom<D::Proto>>::Error>,
54{
55 type Output = Result<Option<D>>;
56 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
57 let this = self.project();
58 match this.inner.poll(cx) {
59 Poll::Ready(Ok(Some(bytes))) => {
60 let v = D::Proto::decode(&*bytes).context("could not decode proto from bytes")?;
61 let v = D::try_from(v)
62 .map_err(anyhow::Error::from)
63 .context("could not parse domain type from proto")?;
64 Poll::Ready(Ok(Some(v)))
65 }
66 Poll::Ready(Ok(None)) => Poll::Ready(Ok(None)),
67 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
68 Poll::Pending => Poll::Pending,
69 }
70 }
71}