prost_reflect/dynamic/serde/ser/
mod.rs
1mod wkt;
2
3use base64::{display::Base64Display, prelude::BASE64_STANDARD};
4
5use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
6
7use crate::{
8 descriptor::Kind,
9 dynamic::{fields::ValueAndDescriptor, serde::SerializeOptions, DynamicMessage, MapKey, Value},
10 ReflectMessage,
11};
12
13struct SerializeWrapper<'a, T> {
14 value: &'a T,
15 options: &'a SerializeOptions,
16}
17
18pub(super) fn serialize_message<S>(
19 message: &DynamicMessage,
20 serializer: S,
21 options: &SerializeOptions,
22) -> Result<S::Ok, S::Error>
23where
24 S: Serializer,
25{
26 SerializeWrapper {
27 value: message,
28 options,
29 }
30 .serialize(serializer)
31}
32
33impl Serialize for SerializeWrapper<'_, DynamicMessage> {
34 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: Serializer,
37 {
38 let message_desc = self.value.descriptor();
39 if let Some(serialize) = wkt::get_well_known_type_serializer(message_desc.full_name()) {
40 serialize(self.value, serializer, self.options)
41 } else {
42 let mut map = serializer.serialize_map(None)?;
43 serialize_dynamic_message_fields(&mut map, self.value, self.options)?;
44 map.end()
45 }
46 }
47}
48
49fn serialize_dynamic_message_fields<S>(
50 map: &mut S,
51 value: &DynamicMessage,
52 options: &SerializeOptions,
53) -> Result<(), S::Error>
54where
55 S: SerializeMap,
56{
57 let fields = value
58 .fields
59 .iter(&value.desc, !options.skip_default_fields, false);
60
61 for field in fields {
62 let (name, value, ref kind) = match field {
63 ValueAndDescriptor::Field(value, ref field_desc) => {
64 let name = if options.use_proto_field_name {
65 field_desc.name()
66 } else {
67 field_desc.json_name()
68 };
69 (name, value, field_desc.kind())
70 }
71 ValueAndDescriptor::Extension(value, ref extension_desc) => {
72 (extension_desc.json_name(), value, extension_desc.kind())
73 }
74 ValueAndDescriptor::Unknown(_) => continue,
75 };
76
77 map.serialize_entry(
78 name,
79 &SerializeWrapper {
80 value: &ValueAndKind {
81 value: value.as_ref(),
82 kind,
83 },
84 options,
85 },
86 )?;
87 }
88
89 Ok(())
90}
91
92struct ValueAndKind<'a> {
93 value: &'a Value,
94 kind: &'a Kind,
95}
96
97impl<'a> Serialize for SerializeWrapper<'a, ValueAndKind<'a>> {
98 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
99 where
100 S: Serializer,
101 {
102 match self.value.value {
103 Value::Bool(value) => serializer.serialize_bool(*value),
104 Value::I32(value) => serializer.serialize_i32(*value),
105 Value::I64(value) => {
106 if self.options.stringify_64_bit_integers {
107 serializer.collect_str(value)
108 } else {
109 serializer.serialize_i64(*value)
110 }
111 }
112 Value::U32(value) => serializer.serialize_u32(*value),
113 Value::U64(value) => {
114 if self.options.stringify_64_bit_integers {
115 serializer.collect_str(value)
116 } else {
117 serializer.serialize_u64(*value)
118 }
119 }
120 Value::F32(value) => {
121 if value.is_finite() {
122 serializer.serialize_f32(*value)
123 } else if *value == f32::INFINITY {
124 serializer.serialize_str("Infinity")
125 } else if *value == f32::NEG_INFINITY {
126 serializer.serialize_str("-Infinity")
127 } else {
128 debug_assert!(value.is_nan());
129 serializer.serialize_str("NaN")
130 }
131 }
132 Value::F64(value) => {
133 if value.is_finite() {
134 serializer.serialize_f64(*value)
135 } else if *value == f64::INFINITY {
136 serializer.serialize_str("Infinity")
137 } else if *value == f64::NEG_INFINITY {
138 serializer.serialize_str("-Infinity")
139 } else {
140 debug_assert!(value.is_nan());
141 serializer.serialize_str("NaN")
142 }
143 }
144 Value::String(value) => serializer.serialize_str(value),
145 Value::Bytes(value) => {
146 serializer.collect_str(&Base64Display::new(value, &BASE64_STANDARD))
147 }
148 Value::EnumNumber(number) => {
149 let enum_ty = match self.value.kind {
150 Kind::Enum(enum_ty) => enum_ty,
151 _ => panic!(
152 "mismatch between DynamicMessage value {:?} and type {:?}",
153 self.value.value, self.value.kind
154 ),
155 };
156
157 if enum_ty.full_name() == "google.protobuf.NullValue" {
158 serializer.serialize_none()
159 } else if self.options.use_enum_numbers {
160 serializer.serialize_i32(*number)
161 } else if let Some(enum_value) = enum_ty.get_value(*number) {
162 serializer.serialize_str(enum_value.name())
163 } else {
164 serializer.serialize_i32(*number)
165 }
166 }
167 Value::Message(message) => message.serialize_with_options(serializer, self.options),
168 Value::List(values) => {
169 let mut list = serializer.serialize_seq(Some(values.len()))?;
170 for value in values {
171 list.serialize_element(&SerializeWrapper {
172 value: &ValueAndKind {
173 value,
174 kind: self.value.kind,
175 },
176 options: self.options,
177 })?;
178 }
179 list.end()
180 }
181 Value::Map(values) => {
182 let value_kind = match self.value.kind {
183 Kind::Message(message) if message.is_map_entry() => {
184 message.map_entry_value_field().kind()
185 }
186 _ => panic!(
187 "mismatch between DynamicMessage value {:?} and type {:?}",
188 self.value.value, self.value.kind
189 ),
190 };
191
192 let mut map = serializer.serialize_map(Some(values.len()))?;
193 for (key, value) in values {
194 map.serialize_entry(
195 &SerializeWrapper {
196 value: key,
197 options: self.options,
198 },
199 &SerializeWrapper {
200 value: &ValueAndKind {
201 value,
202 kind: &value_kind,
203 },
204 options: self.options,
205 },
206 )?;
207 }
208 map.end()
209 }
210 }
211 }
212}
213
214impl Serialize for SerializeWrapper<'_, MapKey> {
215 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
216 where
217 S: Serializer,
218 {
219 match self.value {
220 MapKey::Bool(value) => serializer.collect_str(value),
221 MapKey::I32(value) => serializer.collect_str(value),
222 MapKey::I64(value) => serializer.collect_str(value),
223 MapKey::U32(value) => serializer.collect_str(value),
224 MapKey::U64(value) => serializer.collect_str(value),
225 MapKey::String(value) => serializer.serialize_str(value),
226 }
227 }
228}