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
23        if let (Some(expected), Some(actual)) = (
24            TypeUrl::new(&expected_type_url),
25            TypeUrl::new(&self.type_url),
26        ) {
27            if expected == actual {
28                return M::decode(self.value.as_slice());
29            }
30        }
31
32        let mut err = DecodeError::new(format!(
33            "expected type URL: \"{}\" (got: \"{}\")",
34            expected_type_url, &self.type_url
35        ));
36        err.push("unexpected type URL", "type_url");
37        Err(err)
38    }
39}
40
41impl Name for Any {
42    const PACKAGE: &'static str = PACKAGE;
43    const NAME: &'static str = "Any";
44
45    fn type_url() -> String {
46        type_url_for::<Self>()
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn check_any_serialization() {
56        let message = Timestamp::date(2000, 1, 1).unwrap();
57        let any = Any::from_msg(&message).unwrap();
58        assert_eq!(
59            &any.type_url,
60            "type.googleapis.com/google.protobuf.Timestamp"
61        );
62
63        let message2 = any.to_msg::<Timestamp>().unwrap();
64        assert_eq!(message, message2);
65
66        // Wrong type URL
67        assert!(any.to_msg::<Duration>().is_err());
68    }
69}