juno_rust_proto/
traits.rs

1//! Support traits for Cosmos SDK protobufs.
2
3pub use prost::Message;
4
5use crate::Any;
6use prost::{DecodeError, EncodeError};
7use std::str::FromStr;
8
9/// Associate a type URL with a given proto.
10pub trait TypeUrl: Message {
11    /// Type URL value
12    const TYPE_URL: &'static str;
13}
14
15/// Extension trait for [`Message`].
16pub trait MessageExt: Message {
17    /// Parse this message proto from [`Any`].
18    fn from_any(any: &Any) -> Result<Self, DecodeError>
19    where
20        Self: Default + Sized + TypeUrl,
21    {
22        if any.type_url == Self::TYPE_URL {
23            Ok(Self::decode(&*any.value)?)
24        } else {
25            let mut err = DecodeError::new(format!(
26                "expected type URL: \"{}\" (got: \"{}\")",
27                Self::TYPE_URL,
28                &any.type_url
29            ));
30            err.push("unexpected type URL", "type_url");
31            Err(err)
32        }
33    }
34
35    /// Serialize this message proto as [`Any`].
36    fn to_any(&self) -> Result<Any, EncodeError>
37    where
38        Self: TypeUrl,
39    {
40        self.to_bytes().map(|bytes| Any {
41            type_url: Self::TYPE_URL.to_owned(),
42            value: bytes,
43        })
44    }
45
46    /// Serialize this protobuf message as a byte vector.
47    fn to_bytes(&self) -> Result<Vec<u8>, EncodeError>;
48}
49
50impl<M> MessageExt for M
51where
52    M: prost::Message,
53{
54    fn to_bytes(&self) -> Result<Vec<u8>, EncodeError> {
55        let mut bytes = Vec::new();
56        Message::encode(self, &mut bytes)?;
57        Ok(bytes)
58    }
59}
60
61/// Extension traits for optionally parsing non-empty strings.
62///
63/// This is a common pattern in Cosmos SDK protobufs.
64pub trait ParseOptional: AsRef<str> {
65    /// Parse optional field.
66    fn parse_optional<T: FromStr>(&self) -> Result<Option<T>, T::Err> {
67        if self.as_ref().is_empty() {
68            Ok(None)
69        } else {
70            Ok(Some(self.as_ref().parse()?))
71        }
72    }
73}
74
75impl ParseOptional for str {}
76impl ParseOptional for String {}