1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use crate::{DomainType, Message};
use anyhow::Result;
use cnidarium::StateRead;
use futures::{Stream, StreamExt};
use std::{fmt::Debug, pin::Pin};
use super::future::{DomainFuture, ProtoFuture};
pub trait StateReadProto: StateRead + Send + Sync {
/// Gets a value from the verifiable key-value store as a domain type.
///
/// # Returns
///
/// * `Ok(Some(v))` if the value is present and parseable as a domain type `D`;
/// * `Ok(None)` if the value is missing;
/// * `Err(_)` if the value is present but not parseable as a domain type `D`, or if an underlying storage error occurred.
fn get<D>(&self, key: &str) -> DomainFuture<D, Self::GetRawFut>
where
D: DomainType + std::fmt::Debug,
anyhow::Error: From<<D as TryFrom<D::Proto>>::Error>,
{
DomainFuture {
inner: self.get_raw(key),
_marker: std::marker::PhantomData,
}
}
/// Gets a value from the nonverifiable key-value store as a domain type.
///
/// # Returns
///
/// * `Ok(Some(v))` if the value is present and parseable as a domain type `D`;
/// * `Ok(None)` if the value is missing;
/// * `Err(_)` if the value is present but not parseable as a domain type `D`, or if an underlying storage error occurred.
fn nonverifiable_get<D>(&self, key: &[u8]) -> DomainFuture<D, Self::GetRawFut>
where
D: DomainType + std::fmt::Debug,
anyhow::Error: From<<D as TryFrom<D::Proto>>::Error>,
{
DomainFuture {
inner: self.nonverifiable_get_raw(key),
_marker: std::marker::PhantomData,
}
}
/// Gets a value from the verifiable key-value store as a proto type.
///
/// # Returns
///
/// * `Ok(Some(v))` if the value is present and parseable as a proto type `P`;
/// * `Ok(None)` if the value is missing;
/// * `Err(_)` if the value is present but not parseable as a proto type `P`, or if an underlying storage error occurred.
fn get_proto<P>(&self, key: &str) -> ProtoFuture<P, Self::GetRawFut>
where
P: Message + Default + Debug,
{
ProtoFuture {
inner: self.get_raw(key),
_marker: std::marker::PhantomData,
}
}
/// Retrieve all values for keys matching a prefix from consensus-critical state, as domain types.
#[allow(clippy::type_complexity)]
fn prefix<'a, D>(
&'a self,
prefix: &'a str,
) -> Pin<Box<dyn Stream<Item = Result<(String, D)>> + Send + 'static>>
where
D: DomainType,
anyhow::Error: From<<D as TryFrom<D::Proto>>::Error>,
{
Box::pin(self.prefix_proto(prefix).map(|p| match p {
Ok(p) => match D::try_from(p.1) {
Ok(d) => Ok((p.0, d)),
Err(e) => Err(e.into()),
},
Err(e) => Err(e),
}))
}
/// Retrieve all values for keys matching a prefix from the verifiable key-value store, as proto types.
#[allow(clippy::type_complexity)]
fn prefix_proto<'a, P>(
&'a self,
prefix: &'a str,
) -> Pin<Box<dyn Stream<Item = Result<(String, P)>> + Send + 'static>>
where
P: Message + Default,
{
let o = self.prefix_raw(prefix).map(|r| {
r.and_then(|(key, bytes)| {
Ok((
key,
Message::decode(&*bytes).map_err(|e| anyhow::anyhow!(e))?,
))
})
});
Box::pin(o)
}
}
impl<T: StateRead + ?Sized> StateReadProto for T {}