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 use prost::{bytes, encoding, Message};
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 assert!(any.to_msg::<Duration>().is_err());
68 }
69 #[derive(Clone, PartialEq, Debug, Default)]
70 struct Test {
71 value: i32,
72 }
73
74 impl Message for Test {
75 fn encode_raw(&self, buf: &mut impl bytes::BufMut) {
76 encoding::int32::encode(1, &self.value, buf);
77 }
78
79 fn merge_field(
80 &mut self,
81 tag: u32,
82 wire_type: encoding::WireType,
83 buf: &mut impl bytes::Buf,
84 ctx: encoding::DecodeContext,
85 ) -> Result<(), crate::DecodeError> {
86 if tag == 1 {
87 encoding::int32::merge(wire_type, &mut self.value, buf, ctx)
88 } else {
89 encoding::skip_field(wire_type, tag, buf, ctx)
90 }
91 }
92
93 fn encoded_len(&self) -> usize {
94 encoding::int32::encoded_len(1, &self.value)
95 }
96
97 fn clear(&mut self) {
98 self.value = 0;
99 }
100 }
101
102 impl crate::Name for Test {
103 const PACKAGE: &'static str = ""; const NAME: &'static str = "Test";
105 }
106
107 #[test]
108 fn dynamic_cast_round_trip() {
109 let msg = Test::default();
110 let any = Any::from_msg(&msg).unwrap();
111 let result: Result<Test, _> = any.to_msg();
112 result.expect("This should parse!");
113 }
114
115 #[test]
116 fn default_type_url_should_parse() {
117 let type_url = Test::type_url(); TypeUrl::new(&type_url)
119 .expect("The URL created by the default implementation should parse");
120 }
121}