prost_types/
any.rs

1use super::*;
2
3impl Any {
4    /// Serialize the given message type `M` as [`Any`].
5    pub fn from_msg<M>(msg: &M) -> Result<Self, EncodeError>
6    where
7        M: Name,
8    {
9        let type_url = M::type_url();
10        let mut value = Vec::new();
11        Message::encode(msg, &mut value)?;
12        Ok(Any { type_url, value })
13    }
14
15    /// Decode the given message type `M` from [`Any`], validating that it has
16    /// the expected type URL.
17    pub fn to_msg<M>(&self) -> Result<M, DecodeError>
18    where
19        M: Default + Name + Sized,
20    {
21        let expected_type_url = M::type_url();
22        let actual_type_url = &self.type_url;
23
24        if let (Some(expected), Some(actual)) = (
25            TypeUrl::new(&expected_type_url),
26            TypeUrl::new(actual_type_url),
27        ) {
28            if expected == actual {
29                return M::decode(self.value.as_slice());
30            }
31        }
32
33        Err(DecodeError::new_unexpected_type_url(
34            actual_type_url,
35            expected_type_url,
36        ))
37    }
38}
39
40impl Name for Any {
41    const PACKAGE: &'static str = PACKAGE;
42    const NAME: &'static str = "Any";
43
44    fn type_url() -> String {
45        type_url_for::<Self>()
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn check_any_serialization() {
55        let message = Timestamp::date(2000, 1, 1).unwrap();
56        let any = Any::from_msg(&message).unwrap();
57        assert_eq!(
58            &any.type_url,
59            "type.googleapis.com/google.protobuf.Timestamp"
60        );
61
62        let message2 = any.to_msg::<Timestamp>().unwrap();
63        assert_eq!(message, message2);
64
65        // Wrong type URL
66        assert!(any.to_msg::<Duration>().is_err());
67    }
68}