Skip to content

Commit 131995f

Browse files
committed
implement serde for ListValue, Struct, Value
1 parent c7ed54b commit 131995f

1 file changed

Lines changed: 215 additions & 0 deletions

File tree

prost-types/src/serde.rs

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
use crate::protobuf::value::Kind;
2+
use crate::protobuf::{ListValue, Struct, Value};
3+
use serde::de::{Error, MapAccess, SeqAccess, Visitor};
4+
use serde::ser::{SerializeMap, SerializeSeq};
5+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
6+
7+
impl Serialize for Struct {
8+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9+
where
10+
S: Serializer,
11+
{
12+
let mut s = serializer.serialize_map(Some(self.fields.len()))?;
13+
for (k, v) in &self.fields {
14+
s.serialize_entry(k, v)?;
15+
}
16+
s.end()
17+
}
18+
}
19+
impl<'de> Deserialize<'de> for Struct {
20+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
21+
where
22+
D: Deserializer<'de>,
23+
{
24+
struct StructVisitor;
25+
26+
impl<'de> Visitor<'de> for StructVisitor {
27+
type Value = Struct;
28+
29+
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
30+
formatter.write_str("a map of strings to values")
31+
}
32+
33+
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
34+
where
35+
A: MapAccess<'de>,
36+
{
37+
let mut fields = ::prost::alloc::collections::BTreeMap::new();
38+
while let Some((key, value)) = map.next_entry()? {
39+
fields.insert(key, value);
40+
}
41+
Ok(Struct { fields })
42+
}
43+
}
44+
45+
deserializer.deserialize_map(StructVisitor)
46+
}
47+
}
48+
49+
impl Serialize for Value {
50+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
51+
where
52+
S: Serializer,
53+
{
54+
match &self.kind {
55+
Some(Kind::NullValue(_)) => serializer.serialize_none(),
56+
Some(Kind::NumberValue(v)) => serializer.serialize_f64(*v),
57+
Some(Kind::StringValue(v)) => serializer.serialize_str(v),
58+
Some(Kind::BoolValue(v)) => serializer.serialize_bool(*v),
59+
Some(Kind::StructValue(v)) => v.serialize(serializer),
60+
Some(Kind::ListValue(v)) => v.serialize(serializer),
61+
None => serializer.serialize_none(),
62+
}
63+
}
64+
}
65+
/// Shorthand to create a Value
66+
macro_rules! v {
67+
($kind:expr) => {
68+
Value { kind: Some($kind) }
69+
};
70+
}
71+
impl<'de> Deserialize<'de> for Value {
72+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
73+
where
74+
D: Deserializer<'de>,
75+
{
76+
struct ValueVisitor;
77+
78+
impl<'de> Visitor<'de> for ValueVisitor {
79+
type Value = Value;
80+
81+
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
82+
formatter.write_str("any valid protobuf value")
83+
}
84+
85+
#[inline]
86+
fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
87+
Ok(v!(Kind::BoolValue(value)))
88+
}
89+
90+
#[inline]
91+
fn visit_i64<E: Error>(self, value: i64) -> Result<Value, E> {
92+
let rounded = value as f64;
93+
match rounded as i64 == value {
94+
true => Ok(v!(Kind::NumberValue(value as f64))),
95+
false => Err(Error::custom("i64 cannot be represented by f64")),
96+
}
97+
}
98+
99+
#[inline]
100+
fn visit_u64<E>(self, value: u64) -> Result<Value, E> {
101+
Ok(v!(Kind::NumberValue(value as f64)))
102+
}
103+
104+
#[inline]
105+
fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
106+
Ok(v!(Kind::NumberValue(value)))
107+
}
108+
109+
#[cfg(feature = "std")]
110+
#[inline]
111+
fn visit_str<E>(self, value: &str) -> Result<Value, E>
112+
where
113+
E: Error,
114+
{
115+
self.visit_string(::prost::alloc::string::String::from(value))
116+
}
117+
118+
#[cfg(feature = "std")]
119+
#[inline]
120+
fn visit_string<E>(self, value: ::prost::alloc::string::String) -> Result<Value, E> {
121+
Ok(v!(Kind::StringValue(value)))
122+
}
123+
124+
#[inline]
125+
fn visit_none<E>(self) -> Result<Value, E> {
126+
Ok(v!(Kind::NullValue(0)))
127+
}
128+
129+
#[inline]
130+
fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
131+
where
132+
D: Deserializer<'de>,
133+
{
134+
Deserialize::deserialize(deserializer)
135+
}
136+
137+
#[inline]
138+
fn visit_unit<E>(self) -> Result<Value, E> {
139+
Ok(v!(Kind::NullValue(0)))
140+
}
141+
142+
#[inline]
143+
fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
144+
where
145+
V: SeqAccess<'de>,
146+
{
147+
let mut values = ::prost::alloc::vec::Vec::new();
148+
149+
while let Some(elem) = visitor.next_element()? {
150+
values.push(elem);
151+
}
152+
153+
Ok(v!(Kind::ListValue(ListValue { values })))
154+
}
155+
156+
#[cfg(feature = "std")]
157+
fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
158+
where
159+
V: MapAccess<'de>,
160+
{
161+
let mut fields = ::prost::alloc::collections::BTreeMap::new();
162+
163+
while let Some((key, value)) = visitor.next_entry()? {
164+
fields.insert(key, value);
165+
}
166+
167+
Ok(v!(Kind::StructValue(Struct { fields })))
168+
}
169+
}
170+
171+
deserializer.deserialize_any(ValueVisitor)
172+
}
173+
}
174+
175+
impl Serialize for ListValue {
176+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
177+
where
178+
S: Serializer,
179+
{
180+
let mut s = serializer.serialize_seq(Some(self.values.len()))?;
181+
for v in &self.values {
182+
s.serialize_element(v)?;
183+
}
184+
s.end()
185+
}
186+
}
187+
impl<'de> Deserialize<'de> for ListValue {
188+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
189+
where
190+
D: Deserializer<'de>,
191+
{
192+
struct ListVisitor;
193+
194+
impl<'de> Visitor<'de> for ListVisitor {
195+
type Value = ListValue;
196+
197+
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
198+
formatter.write_str("a map of strings to values")
199+
}
200+
201+
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
202+
where
203+
A: SeqAccess<'de>,
204+
{
205+
let mut values = ::prost::alloc::vec::Vec::new();
206+
while let Some((key, value)) = seq.next_element()? {
207+
values.insert(key, value);
208+
}
209+
Ok(ListValue { values })
210+
}
211+
}
212+
213+
deserializer.deserialize_map(ListVisitor)
214+
}
215+
}

0 commit comments

Comments
 (0)