prost_reflect/dynamic/serde/mod.rs
1mod case;
2mod de;
3mod ser;
4
5use serde::{
6 de::{DeserializeSeed, Deserializer},
7 ser::{Serialize, Serializer},
8};
9
10use crate::{DynamicMessage, MessageDescriptor};
11
12/// Options to control serialization of messages.
13///
14/// Used by [`DynamicMessage::serialize_with_options()`].
15#[derive(Debug, Clone)]
16#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
17pub struct SerializeOptions {
18 stringify_64_bit_integers: bool,
19 use_enum_numbers: bool,
20 use_proto_field_name: bool,
21 skip_default_fields: bool,
22}
23
24/// Options to control deserialization of messages.
25///
26/// Used by [`DynamicMessage::deserialize_with_options()`].
27#[derive(Debug, Clone)]
28#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
29pub struct DeserializeOptions {
30 deny_unknown_fields: bool,
31}
32
33#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
34impl Serialize for DynamicMessage {
35 /// Serialize this message into `serializer` using the [canonical JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json).
36 ///
37 /// # Examples
38 ///
39 /// ```
40 /// # use prost::Message;
41 /// # use prost_types::FileDescriptorSet;
42 /// # use prost_reflect::{DynamicMessage, DescriptorPool, Value};
43 /// # use serde1::Serialize;
44 /// # let pool = DescriptorPool::decode(include_bytes!("../../file_descriptor_set.bin").as_ref()).unwrap();
45 /// # let message_descriptor = pool.get_message_by_name("package.MyMessage").unwrap();
46 /// let dynamic_message = DynamicMessage::decode(message_descriptor, b"\x08\x96\x01".as_ref()).unwrap();
47 /// let mut serializer = serde_json::Serializer::new(vec![]);
48 /// dynamic_message.serialize(&mut serializer).unwrap();
49 /// assert_eq!(serializer.into_inner(), b"{\"foo\":150}");
50 /// ```
51 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52 where
53 S: Serializer,
54 {
55 self.serialize_with_options(serializer, &Default::default())
56 }
57}
58
59#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
60impl<'de> DeserializeSeed<'de> for MessageDescriptor {
61 type Value = DynamicMessage;
62
63 /// Deserialize a [`DynamicMessage`] from `deserializer` using the [canonical JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json).
64 ///
65 /// # Examples
66 ///
67 /// ```
68 /// # use prost::Message;
69 /// # use prost_reflect::{DynamicMessage, DescriptorPool, Value};
70 /// # use serde1 as serde;
71 /// # let pool = DescriptorPool::decode(include_bytes!("../../file_descriptor_set.bin").as_ref()).unwrap();
72 /// # let message_descriptor = pool.get_message_by_name("package.MyMessage").unwrap();
73 /// use serde::de::DeserializeSeed;
74 ///
75 /// let json = r#"{ "foo": 150 }"#;
76 /// let mut deserializer = serde_json::de::Deserializer::from_str(json);
77 /// let dynamic_message = message_descriptor.deserialize(&mut deserializer).unwrap();
78 /// deserializer.end().unwrap();
79 ///
80 /// assert_eq!(dynamic_message.get_field_by_name("foo").unwrap().as_ref(), &Value::I32(150));
81 /// ```
82 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
83 where
84 D: Deserializer<'de>,
85 {
86 DynamicMessage::deserialize(self, deserializer)
87 }
88}
89
90impl DynamicMessage {
91 /// Serialize this message into `serializer` using the encoding specified by `options`.
92 ///
93 /// # Examples
94 ///
95 /// ```
96 /// # use prost::Message;
97 /// # use prost_types::FileDescriptorSet;
98 /// # use prost_reflect::{DynamicMessage, DescriptorPool, Value, SerializeOptions};
99 /// # use serde1::Serialize;
100 /// # let pool = DescriptorPool::decode(include_bytes!("../../file_descriptor_set.bin").as_ref()).unwrap();
101 /// # let message_descriptor = pool.get_message_by_name("package.MyMessage").unwrap();
102 /// let dynamic_message = DynamicMessage::new(message_descriptor);
103 /// let mut serializer = serde_json::Serializer::new(vec![]);
104 /// let mut options = SerializeOptions::new().skip_default_fields(false);
105 /// dynamic_message.serialize_with_options(&mut serializer, &options).unwrap();
106 /// assert_eq!(serializer.into_inner(), b"{\"foo\":0}");
107 /// ```
108 #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
109 pub fn serialize_with_options<S>(
110 &self,
111 serializer: S,
112 options: &SerializeOptions,
113 ) -> Result<S::Ok, S::Error>
114 where
115 S: Serializer,
116 {
117 ser::serialize_message(self, serializer, options)
118 }
119
120 /// Deserialize an instance of the message type described by `desc` from `deserializer`.
121 ///
122 /// # Examples
123 ///
124 /// ```
125 /// # use prost::Message;
126 /// # use prost_reflect::{DynamicMessage, DescriptorPool, Value};
127 /// # use serde1 as serde;
128 /// # let pool = DescriptorPool::decode(include_bytes!("../../file_descriptor_set.bin").as_ref()).unwrap();
129 /// # let message_descriptor = pool.get_message_by_name("package.MyMessage").unwrap();
130 /// let json = r#"{ "foo": 150 }"#;
131 /// let mut deserializer = serde_json::de::Deserializer::from_str(json);
132 /// let dynamic_message = DynamicMessage::deserialize(message_descriptor, &mut deserializer).unwrap();
133 /// deserializer.end().unwrap();
134 ///
135 /// assert_eq!(dynamic_message.get_field_by_name("foo").unwrap().as_ref(), &Value::I32(150));
136 /// ```
137 #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
138 pub fn deserialize<'de, D>(desc: MessageDescriptor, deserializer: D) -> Result<Self, D::Error>
139 where
140 D: Deserializer<'de>,
141 {
142 Self::deserialize_with_options(desc, deserializer, &Default::default())
143 }
144
145 /// Deserialize an instance of the message type described by `desc` from `deserializer`, using
146 /// the encoding specified by `options`.
147 ///
148 /// # Examples
149 ///
150 /// ```
151 /// # use prost::Message;
152 /// # use prost_reflect::{DynamicMessage, DescriptorPool, Value, DeserializeOptions};
153 /// # use serde1 as serde;
154 /// # let pool = DescriptorPool::decode(include_bytes!("../../file_descriptor_set.bin").as_ref()).unwrap();
155 /// # let message_descriptor = pool.get_message_by_name("package.MyMessage").unwrap();
156 /// let json = r#"{ "foo": 150, "unknown": true }"#;
157 /// let mut deserializer = serde_json::de::Deserializer::from_str(json);
158 /// let options = DeserializeOptions::new().deny_unknown_fields(false);
159 /// let dynamic_message = DynamicMessage::deserialize_with_options(message_descriptor, &mut deserializer, &options).unwrap();
160 /// deserializer.end().unwrap();
161 ///
162 /// assert_eq!(dynamic_message.get_field_by_name("foo").unwrap().as_ref(), &Value::I32(150));
163 /// ```
164 #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
165 pub fn deserialize_with_options<'de, D>(
166 desc: MessageDescriptor,
167 deserializer: D,
168 options: &DeserializeOptions,
169 ) -> Result<Self, D::Error>
170 where
171 D: Deserializer<'de>,
172 {
173 de::deserialize_message(&desc, deserializer, options)
174 }
175}
176
177impl DeserializeOptions {
178 /// Creates a new instance of [`DeserializeOptions`], with the default options chosen to conform to
179 /// the standard JSON mapping.
180 pub const fn new() -> Self {
181 DeserializeOptions {
182 deny_unknown_fields: true,
183 }
184 }
185
186 /// Whether to error during deserialization when encountering unknown message fields.
187 ///
188 /// The default value is `true`.
189 pub const fn deny_unknown_fields(mut self, yes: bool) -> Self {
190 self.deny_unknown_fields = yes;
191 self
192 }
193}
194
195impl Default for DeserializeOptions {
196 fn default() -> Self {
197 Self::new()
198 }
199}
200
201impl SerializeOptions {
202 /// Creates a new instance of [`SerializeOptions`], with the default options chosen to conform to
203 /// the standard JSON mapping.
204 pub const fn new() -> Self {
205 SerializeOptions {
206 stringify_64_bit_integers: true,
207 use_enum_numbers: false,
208 use_proto_field_name: false,
209 skip_default_fields: true,
210 }
211 }
212
213 /// Whether to encode 64-bit integral types as strings.
214 ///
215 /// The spec requires encoding 64-bit integers as strings, to prevent loss of precision in JSON
216 /// when the value cannot be represented exactly by a double. If this option is disabled, all
217 /// numbers will be serialized as their corresponding serde types instead.
218 ///
219 /// The default value is `true`.
220 pub const fn stringify_64_bit_integers(mut self, yes: bool) -> Self {
221 self.stringify_64_bit_integers = yes;
222 self
223 }
224
225 /// Whether to encode enum values as their numeric value.
226 ///
227 /// If `true`, enum values will be serialized as their integer values. Otherwise, they will be
228 /// serialized as the string value specified in the proto file.
229 ///
230 /// The default value is `false`.
231 pub const fn use_enum_numbers(mut self, yes: bool) -> Self {
232 self.use_enum_numbers = yes;
233 self
234 }
235
236 /// Whether to use the proto field name instead of the lowerCamelCase name in JSON field names.
237 ///
238 /// The default value is `false`.
239 pub const fn use_proto_field_name(mut self, yes: bool) -> Self {
240 self.use_proto_field_name = yes;
241 self
242 }
243
244 /// Whether to skip fields which have their default value.
245 ///
246 /// If `true`, any fields for which [`has_field`][DynamicMessage::has_field] returns `false` will
247 /// not be serialized. If `false`, they will be serialized with their default value.
248 ///
249 /// The default value is `true`.
250 pub const fn skip_default_fields(mut self, yes: bool) -> Self {
251 self.skip_default_fields = yes;
252 self
253 }
254}
255
256impl Default for SerializeOptions {
257 fn default() -> Self {
258 Self::new()
259 }
260}
261
262const MAX_DURATION_SECONDS: u64 = 315_576_000_000;
263const MAX_DURATION_NANOS: u32 = 999_999_999;
264
265const MIN_TIMESTAMP_SECONDS: i64 = -62135596800;
266const MAX_TIMESTAMP_SECONDS: i64 = 253402300799;
267
268fn is_well_known_type(full_name: &str) -> bool {
269 matches!(
270 full_name,
271 "google.protobuf.Any"
272 | "google.protobuf.Timestamp"
273 | "google.protobuf.Duration"
274 | "google.protobuf.Struct"
275 | "google.protobuf.FloatValue"
276 | "google.protobuf.DoubleValue"
277 | "google.protobuf.Int32Value"
278 | "google.protobuf.Int64Value"
279 | "google.protobuf.UInt32Value"
280 | "google.protobuf.UInt64Value"
281 | "google.protobuf.BoolValue"
282 | "google.protobuf.StringValue"
283 | "google.protobuf.BytesValue"
284 | "google.protobuf.FieldMask"
285 | "google.protobuf.ListValue"
286 | "google.protobuf.Value"
287 | "google.protobuf.Empty"
288 )
289}
290
291fn check_duration(duration: &prost_types::Duration) -> Result<(), &'static str> {
292 if duration.seconds.unsigned_abs() > MAX_DURATION_SECONDS
293 || duration.nanos.unsigned_abs() > MAX_DURATION_NANOS
294 {
295 Err("duration out of range")
296 } else {
297 Ok(())
298 }
299}
300
301fn check_timestamp(timestamp: &prost_types::Timestamp) -> Result<(), &'static str> {
302 if timestamp.seconds < MIN_TIMESTAMP_SECONDS || MAX_TIMESTAMP_SECONDS < timestamp.seconds {
303 Err("timestamp out of range")
304 } else {
305 Ok(())
306 }
307}