google_cloud_wkt/
message.rs1pub(crate) type Map = serde_json::Map<String, serde_json::Value>;
18use crate::AnyError as Error;
19
20pub trait Message: serde::ser::Serialize + serde::de::DeserializeOwned {
26 fn typename() -> &'static str;
28
29 #[doc(hidden)]
31 #[allow(private_interfaces)]
32 fn serializer() -> impl MessageSerializer<Self> {
33 DefaultSerializer::<Self>::new()
34 }
35}
36
37pub(crate) trait MessageSerializer<T> {
40 fn serialize_to_map(&self, message: &T) -> Result<Map, Error>;
42
43 fn deserialize_from_map(&self, map: &Map) -> Result<T, Error>;
45}
46
47pub(crate) struct DefaultSerializer<T> {
49 _phantom: std::marker::PhantomData<T>,
50}
51
52impl<T> DefaultSerializer<T> {
53 pub fn new() -> Self {
54 Self {
55 _phantom: std::marker::PhantomData,
56 }
57 }
58}
59
60impl<T> MessageSerializer<T> for DefaultSerializer<T>
61where
62 T: Message,
63{
64 fn serialize_to_map(&self, message: &T) -> Result<Map, Error> {
65 to_json_object(message)
66 }
67
68 fn deserialize_from_map(&self, map: &Map) -> Result<T, Error> {
69 from_object(map)
70 }
71}
72
73pub(crate) struct ValueSerializer<T> {
75 _phantom: std::marker::PhantomData<T>,
76}
77
78impl<T> ValueSerializer<T> {
79 pub fn new() -> Self {
80 Self {
81 _phantom: std::marker::PhantomData,
82 }
83 }
84}
85
86impl<T> MessageSerializer<T> for ValueSerializer<T>
87where
88 T: Message,
89{
90 fn serialize_to_map(&self, message: &T) -> Result<Map, Error> {
91 to_json_other(message)
92 }
93
94 fn deserialize_from_map(&self, map: &Map) -> Result<T, Error> {
95 from_other(map)
96 }
97}
98
99pub(crate) fn to_json_object<T>(message: &T) -> Result<Map, Error>
106where
107 T: Message,
108{
109 use serde_json::Value;
110
111 let value = serde_json::to_value(message).map_err(Error::ser)?;
112 match value {
113 Value::Object(mut map) => {
114 map.insert(
115 "@type".to_string(),
116 Value::String(T::typename().to_string()),
117 );
118 Ok(map)
119 }
120 _ => Err(unexpected_json_type()),
121 }
122}
123
124pub(crate) fn to_json_other<T>(message: &T) -> Result<Map, Error>
133where
134 T: Message,
135{
136 let value = serde_json::to_value(message).map_err(Error::ser)?;
137 let mut map = crate::message::Map::new();
138 map.insert("@type".to_string(), T::typename().into());
139 map.insert("value".to_string(), value);
140 Ok(map)
141}
142
143pub(crate) fn from_object<T>(map: &Map) -> Result<T, Error>
145where
146 T: Message,
147{
148 let map = map
149 .iter()
150 .filter_map(|(k, v)| {
151 if k == "@type" {
152 return None;
153 }
154 Some((k.clone(), v.clone()))
155 })
156 .collect();
157 serde_json::from_value::<T>(serde_json::Value::Object(map)).map_err(Error::deser)
158}
159
160pub(crate) fn from_other<T>(map: &Map) -> Result<T, Error>
162where
163 T: Message,
164{
165 map.get("value")
166 .map(|v| serde_json::from_value::<T>(v.clone()))
167 .ok_or_else(missing_value_field)?
168 .map_err(Error::deser)
169}
170
171pub(crate) fn missing_value_field() -> Error {
172 Error::deser("value field is missing")
173}
174
175fn unexpected_json_type() -> Error {
176 Error::ser("unexpected JSON type, only Object and String are supported")
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182 use serde_json::json;
183
184 #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
185 struct TestMessage {
186 #[serde(flatten)]
187 _unknown_fields: serde_json::Map<String, serde_json::Value>,
188 }
189
190 impl Message for TestMessage {
191 fn typename() -> &'static str {
192 "TestMessage"
193 }
194 }
195
196 #[test]
197 fn drop_type_field() {
198 let input = json!({
199 "@type": "TestMessage",
200 "a": 1,
201 "b": 2,
202 });
203 let map = input.as_object().cloned().unwrap();
204
205 let serializer = TestMessage::serializer();
206 let test = serializer.deserialize_from_map(&map).unwrap();
207
208 assert!(test._unknown_fields.get("@type").is_none(), "{test:?}");
209 }
210}