prost_reflect/dynamic/serde/de/
mod.rs
1mod kind;
2mod wkt;
3
4use std::fmt;
5
6use prost::Message;
7use serde::de::{DeserializeSeed, Deserializer, Error, Visitor};
8
9use crate::{
10 dynamic::{fields::FieldDescriptorLike, serde::DeserializeOptions, DynamicMessage, Value},
11 EnumDescriptor, Kind, MessageDescriptor,
12};
13
14pub(super) fn deserialize_message<'de, D>(
15 desc: &MessageDescriptor,
16 deserializer: D,
17 options: &DeserializeOptions,
18) -> Result<DynamicMessage, D::Error>
19where
20 D: Deserializer<'de>,
21{
22 match desc.full_name() {
23 "google.protobuf.Any" => deserializer
24 .deserialize_any(wkt::GoogleProtobufAnyVisitor(desc.parent_pool(), options))
25 .and_then(|timestamp| make_message(desc, timestamp)),
26 "google.protobuf.Timestamp" => deserializer
27 .deserialize_str(wkt::GoogleProtobufTimestampVisitor)
28 .and_then(|timestamp| make_message(desc, timestamp)),
29 "google.protobuf.Duration" => deserializer
30 .deserialize_str(wkt::GoogleProtobufDurationVisitor)
31 .and_then(|duration| make_message(desc, duration)),
32 "google.protobuf.FloatValue" => deserializer
33 .deserialize_any(kind::FloatVisitor)
34 .and_then(|v| make_message(desc, v)),
35 "google.protobuf.DoubleValue" => deserializer
36 .deserialize_any(kind::DoubleVisitor)
37 .and_then(|v| make_message(desc, v)),
38 "google.protobuf.Int32Value" => deserializer
39 .deserialize_any(kind::Int32Visitor)
40 .and_then(|v| make_message(desc, v)),
41 "google.protobuf.Int64Value" => deserializer
42 .deserialize_any(kind::Int64Visitor)
43 .and_then(|v| make_message(desc, v)),
44 "google.protobuf.UInt32Value" => deserializer
45 .deserialize_any(kind::Uint32Visitor)
46 .and_then(|v| make_message(desc, v)),
47 "google.protobuf.UInt64Value" => deserializer
48 .deserialize_any(kind::Uint64Visitor)
49 .and_then(|v| make_message(desc, v)),
50 "google.protobuf.BoolValue" => deserializer
51 .deserialize_any(kind::BoolVisitor)
52 .and_then(|v| make_message(desc, v)),
53 "google.protobuf.StringValue" => deserializer
54 .deserialize_any(kind::StringVisitor)
55 .and_then(|v| make_message(desc, v)),
56 "google.protobuf.BytesValue" => deserializer
57 .deserialize_any(kind::BytesVisitor)
58 .and_then(|v| make_message(desc, v)),
59 "google.protobuf.FieldMask" => deserializer
60 .deserialize_str(wkt::GoogleProtobufFieldMaskVisitor)
61 .and_then(|field_mask| make_message(desc, field_mask)),
62 "google.protobuf.Struct" => deserializer
63 .deserialize_map(wkt::GoogleProtobufStructVisitor)
64 .and_then(|value| make_message(desc, value)),
65 "google.protobuf.ListValue" => deserializer
66 .deserialize_seq(wkt::GoogleProtobufListVisitor)
67 .and_then(|list| make_message(desc, list)),
68 "google.protobuf.Value" => deserializer
69 .deserialize_any(wkt::GoogleProtobufValueVisitor)
70 .and_then(|value| make_message(desc, value)),
71 "google.protobuf.Empty" => deserializer
72 .deserialize_map(wkt::GoogleProtobufEmptyVisitor)
73 .and_then(|empty| make_message(desc, empty)),
74 _ => deserializer.deserialize_map(kind::MessageVisitor(desc, options)),
75 }
76}
77
78fn deserialize_enum<'de, D>(
79 desc: &EnumDescriptor,
80 deserializer: D,
81 options: &DeserializeOptions,
82) -> Result<Option<i32>, D::Error>
83where
84 D: Deserializer<'de>,
85{
86 match desc.full_name() {
87 "google.protobuf.NullValue" => {
88 deserializer.deserialize_any(wkt::GoogleProtobufNullVisitor(options))
89 }
90 _ => deserializer.deserialize_any(kind::EnumVisitor(desc, options)),
91 }
92}
93
94struct MessageSeed<'a>(&'a MessageDescriptor, &'a DeserializeOptions);
95
96impl<'de> DeserializeSeed<'de> for MessageSeed<'_> {
97 type Value = DynamicMessage;
98
99 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
100 where
101 D: Deserializer<'de>,
102 {
103 deserialize_message(self.0, deserializer, self.1)
104 }
105}
106
107struct FieldDescriptorSeed<'a, T>(&'a T, &'a DeserializeOptions);
108
109impl<'de, T> DeserializeSeed<'de> for FieldDescriptorSeed<'_, T>
110where
111 T: FieldDescriptorLike,
112{
113 type Value = Option<Value>;
114
115 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
116 where
117 D: Deserializer<'de>,
118 {
119 if self.0.is_list() {
120 Ok(Some(Value::List(deserializer.deserialize_any(
121 kind::ListVisitor(&self.0.kind(), self.1),
122 )?)))
123 } else if self.0.is_map() {
124 Ok(Some(Value::Map(deserializer.deserialize_any(
125 kind::MapVisitor(&self.0.kind(), self.1),
126 )?)))
127 } else {
128 kind::KindSeed(&self.0.kind(), self.1).deserialize(deserializer)
129 }
130 }
131}
132
133struct OptionalFieldDescriptorSeed<'a, T>(&'a T, &'a DeserializeOptions);
134
135impl<'de, T> DeserializeSeed<'de> for OptionalFieldDescriptorSeed<'_, T>
136where
137 T: FieldDescriptorLike,
138{
139 type Value = Option<Value>;
140
141 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
142 where
143 D: Deserializer<'de>,
144 {
145 deserializer.deserialize_option(self)
146 }
147}
148
149impl<'de, T> Visitor<'de> for OptionalFieldDescriptorSeed<'_, T>
150where
151 T: FieldDescriptorLike,
152{
153 type Value = Option<Value>;
154
155 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
156 write!(f, "option")
157 }
158
159 #[inline]
160 fn visit_unit<E>(self) -> Result<Self::Value, E>
161 where
162 E: Error,
163 {
164 self.visit_none()
165 }
166
167 #[inline]
168 fn visit_none<E>(self) -> Result<Self::Value, E>
169 where
170 E: Error,
171 {
172 match self.0.kind() {
173 Kind::Message(message_desc) if message_desc.full_name() == "google.protobuf.Value" => {
174 make_message(
175 &message_desc,
176 prost_types::Value {
177 kind: Some(prost_types::value::Kind::NullValue(0)),
178 },
179 )
180 .map(|v| Some(Value::Message(v)))
181 }
182 Kind::Enum(enum_desc) if enum_desc.full_name() == "google.protobuf.NullValue" => {
183 Ok(Some(Value::EnumNumber(0)))
184 }
185 _ => Ok(None),
186 }
187 }
188
189 #[inline]
190 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
191 where
192 D: Deserializer<'de>,
193 {
194 FieldDescriptorSeed(self.0, self.1).deserialize(deserializer)
195 }
196}
197
198fn make_message<E: Error, T: Message>(
199 desc: &MessageDescriptor,
200 message: T,
201) -> Result<DynamicMessage, E> {
202 let mut dynamic = DynamicMessage::new(desc.clone());
203 dynamic
204 .transcode_from(&message)
205 .map_err(|err| Error::custom(format!("error decoding: {}", err)))?;
206 Ok(dynamic)
207}