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}