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 #[cfg_attr(not(feature = "_internal-semver"), doc(hidden))]
31 fn serializer() -> impl MessageSerializer<Self> {
32 DefaultSerializer::<Self>::new()
33 }
34}
35
36pub(crate) mod sealed {
37 pub trait MessageSerializer {}
38}
39
40#[cfg_attr(not(feature = "_internal-semver"), doc(hidden))]
41pub trait MessageSerializer<T>: sealed::MessageSerializer {
44 fn serialize_to_map(&self, message: &T) -> Result<Map, Error>;
46
47 fn deserialize_from_map(&self, map: &Map) -> Result<T, Error>;
49}
50
51pub(crate) struct DefaultSerializer<T> {
53 _phantom: std::marker::PhantomData<T>,
54}
55
56impl<T> DefaultSerializer<T> {
57 pub fn new() -> Self {
58 Self {
59 _phantom: std::marker::PhantomData,
60 }
61 }
62}
63
64#[cfg_attr(not(feature = "_internal-semver"), doc(hidden))]
65impl<T> sealed::MessageSerializer for DefaultSerializer<T> {}
66
67impl<T> MessageSerializer<T> for DefaultSerializer<T>
68where
69 T: Message,
70{
71 fn serialize_to_map(&self, message: &T) -> Result<Map, Error> {
72 to_json_object(message)
73 }
74
75 fn deserialize_from_map(&self, map: &Map) -> Result<T, Error> {
76 from_object(map)
77 }
78}
79
80pub(crate) struct ValueSerializer<T> {
82 _phantom: std::marker::PhantomData<T>,
83}
84
85impl<T> ValueSerializer<T> {
86 pub fn new() -> Self {
87 Self {
88 _phantom: std::marker::PhantomData,
89 }
90 }
91}
92
93#[cfg_attr(not(feature = "_internal-semver"), doc(hidden))]
94impl<T> sealed::MessageSerializer for ValueSerializer<T> {}
95
96impl<T> MessageSerializer<T> for ValueSerializer<T>
97where
98 T: Message,
99{
100 fn serialize_to_map(&self, message: &T) -> Result<Map, Error> {
101 to_json_other(message)
102 }
103
104 fn deserialize_from_map(&self, map: &Map) -> Result<T, Error> {
105 from_other(map)
106 }
107}
108
109pub(crate) fn to_json_object<T>(message: &T) -> Result<Map, Error>
116where
117 T: Message,
118{
119 use serde_json::Value;
120
121 let value = serde_json::to_value(message).map_err(Error::ser)?;
122 match value {
123 Value::Object(mut map) => {
124 map.insert(
125 "@type".to_string(),
126 Value::String(T::typename().to_string()),
127 );
128 Ok(map)
129 }
130 _ => Err(unexpected_json_type()),
131 }
132}
133
134pub(crate) fn to_json_other<T>(message: &T) -> Result<Map, Error>
143where
144 T: Message,
145{
146 let value = serde_json::to_value(message).map_err(Error::ser)?;
147 let mut map = crate::message::Map::new();
148 map.insert("@type".to_string(), T::typename().into());
149 map.insert("value".to_string(), value);
150 Ok(map)
151}
152
153pub(crate) fn from_object<T>(map: &Map) -> Result<T, Error>
155where
156 T: Message,
157{
158 let map = map
159 .iter()
160 .filter_map(|(k, v)| {
161 if k == "@type" {
162 return None;
163 }
164 Some((k.clone(), v.clone()))
165 })
166 .collect();
167 serde_json::from_value::<T>(serde_json::Value::Object(map)).map_err(Error::deser)
168}
169
170pub(crate) fn from_other<T>(map: &Map) -> Result<T, Error>
172where
173 T: Message,
174{
175 map.get("value")
176 .map(|v| serde_json::from_value::<T>(v.clone()))
177 .ok_or_else(missing_value_field)?
178 .map_err(Error::deser)
179}
180
181pub(crate) fn missing_value_field() -> Error {
182 Error::deser("value field is missing")
183}
184
185fn unexpected_json_type() -> Error {
186 Error::ser("unexpected JSON type, only Object and String are supported")
187}
188
189#[cfg(test)]
190mod tests {
191 use super::*;
192 use serde_json::json;
193
194 #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
195 struct TestMessage {
196 #[serde(flatten)]
197 _unknown_fields: serde_json::Map<String, serde_json::Value>,
198 }
199
200 impl Message for TestMessage {
201 fn typename() -> &'static str {
202 "TestMessage"
203 }
204 }
205
206 #[test]
207 fn drop_type_field() {
208 let input = json!({
209 "@type": "TestMessage",
210 "a": 1,
211 "b": 2,
212 });
213 let map = input.as_object().cloned().unwrap();
214
215 let serializer = TestMessage::serializer();
216 let test = serializer.deserialize_from_map(&map).unwrap();
217
218 assert!(test._unknown_fields.get("@type").is_none(), "{test:?}");
219 }
220}