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}