substrait_explain/extensions/
any.rs

1use prost::{Message, Name};
2
3use crate::extensions::registry::ExtensionError;
4
5/// A wrapper around the protobuf `Any` type. Converts to or from
6/// `prost_types::Any` or `pbjson_types::Any`.
7#[derive(Debug, Clone, PartialEq)]
8pub struct Any {
9    pub type_url: String,
10    pub value: Vec<u8>,
11}
12
13/// A reference to a protobuf `Any` type. Can be created from references to
14/// [`prost_types::Any`](prost_types::Any),
15/// [`pbjson_types::Any`](pbjson_types::Any), or our own [`Any`](Any) type.
16#[derive(Debug, Copy, Clone, PartialEq)]
17pub struct AnyRef<'a> {
18    pub type_url: &'a str,
19    pub value: &'a [u8],
20}
21
22impl<'a> AnyRef<'a> {
23    /// Create a new [`AnyRef`]
24    pub fn new(type_url: &'a str, value: &'a [u8]) -> Self {
25        Self { type_url, value }
26    }
27
28    /// Decode this [`AnyRef`] as a specific protobuf message type
29    pub fn decode<M>(&self) -> Result<M, ExtensionError>
30    where
31        M: prost::Message + Name + Default,
32    {
33        if self.type_url != M::type_url() {
34            return Err(ExtensionError::TypeUrlMismatch {
35                expected: M::type_url(),
36                actual: self.type_url.to_string(),
37            });
38        }
39
40        let message = M::decode(self.value).map_err(ExtensionError::DecodeFailed)?;
41
42        Ok(message)
43    }
44}
45
46impl<'a> From<&'a Any> for AnyRef<'a> {
47    fn from(any: &'a Any) -> Self {
48        Self {
49            type_url: &any.type_url,
50            value: &any.value,
51        }
52    }
53}
54
55impl<'a> From<&'a prost_types::Any> for AnyRef<'a> {
56    fn from(any: &'a prost_types::Any) -> Self {
57        Self {
58            type_url: &any.type_url,
59            value: &any.value,
60        }
61    }
62}
63
64#[cfg(feature = "serde")]
65impl<'a> From<&'a pbjson_types::Any> for AnyRef<'a> {
66    fn from(any: &'a pbjson_types::Any) -> Self {
67        Self {
68            type_url: &any.type_url,
69            value: &any.value,
70        }
71    }
72}
73
74impl Any {
75    /// Create a new `Any` for the given type from the given value bytes.
76    pub fn new(type_url: String, value: Vec<u8>) -> Self {
77        Self { type_url, value }
78    }
79
80    /// Convert this [`Any`] to a [`AnyRef`].
81    pub fn as_ref(&self) -> AnyRef<'_> {
82        AnyRef::from(self)
83    }
84
85    /// Decode this [`Any`] as a specific protobuf message type
86    pub fn decode<M>(&self) -> Result<M, ExtensionError>
87    where
88        M: prost::Message + Name + Default,
89    {
90        self.as_ref().decode()
91    }
92
93    /// Encode a protobuf message into an [`Any`].
94    pub fn encode<M: Message + Name + Default>(message: &M) -> Result<Self, ExtensionError> {
95        let mut buf = Vec::new();
96        message
97            .encode(&mut buf)
98            .map_err(ExtensionError::EncodeFailed)?;
99
100        Ok(Any {
101            type_url: M::type_url(),
102            value: buf,
103        })
104    }
105}
106
107impl From<prost_types::Any> for Any {
108    fn from(any: prost_types::Any) -> Self {
109        Self {
110            type_url: any.type_url,
111            value: any.value.to_vec(),
112        }
113    }
114}
115
116impl From<Any> for prost_types::Any {
117    fn from(any: Any) -> Self {
118        Self {
119            type_url: any.type_url,
120            value: any.value,
121        }
122    }
123}
124
125#[cfg(feature = "serde")]
126impl From<pbjson_types::Any> for Any {
127    fn from(any: pbjson_types::Any) -> Self {
128        Self {
129            type_url: any.type_url,
130            value: any.value.to_vec(),
131        }
132    }
133}
134
135#[cfg(feature = "serde")]
136impl From<Any> for pbjson_types::Any {
137    fn from(any: Any) -> Self {
138        Self {
139            type_url: any.type_url,
140            value: any.value.into(),
141        }
142    }
143}