1use super::*;
2
3impl Any {
4 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 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 assert!(any.to_msg::<Duration>().is_err());
67 }
68}