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