proto_types/
protobuf_impls.rs

1#[cfg(feature = "serde")]
2mod serde {
3  use base64::{prelude::BASE64_STANDARD, Engine};
4  use prost::bytes::Bytes;
5  use serde::{
6    de::{self, MapAccess, SeqAccess, Visitor},
7    ser::Serializer,
8    Deserialize, Deserializer, Serialize,
9  };
10
11  use crate::{value::Kind, BytesValue, ListValue, NullValue, Struct, Value};
12
13  impl Serialize for ListValue {
14    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
15    where
16      S: Serializer,
17    {
18      self.values.serialize(serializer)
19    }
20  }
21
22  impl<'de> Deserialize<'de> for ListValue {
23    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24    where
25      D: de::Deserializer<'de>,
26    {
27      let values = <::prost::alloc::vec::Vec<Value>>::deserialize(deserializer)?;
28      Ok(ListValue { values })
29    }
30  }
31
32  impl Serialize for Value {
33    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
34    where
35      S: Serializer,
36    {
37      match self.kind {
38        Some(Kind::NullValue(_)) => serializer.serialize_unit(),
39        Some(Kind::NumberValue(v)) => serializer.serialize_f64(v),
40        Some(Kind::StringValue(ref v)) => serializer.serialize_str(v),
41        Some(Kind::BoolValue(v)) => serializer.serialize_bool(v),
42        Some(Kind::StructValue(ref v)) => v.serialize(serializer),
43        Some(Kind::ListValue(ref v)) => v.serialize(serializer),
44        None => Err(serde::ser::Error::custom("Value must have a variant set")),
45      }
46    }
47  }
48
49  impl<'de> Deserialize<'de> for Value {
50    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
51    where
52      D: de::Deserializer<'de>,
53    {
54      deserializer.deserialize_any(ValueVisitor)
55    }
56  }
57
58  struct ValueVisitor;
59
60  impl<'de> Visitor<'de> for ValueVisitor {
61    type Value = Value;
62
63    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
64      formatter.write_str("a JSON value (null, number, string, boolean, object, or array)")
65    }
66
67    fn visit_unit<E>(self) -> Result<Self::Value, E>
68    where
69      E: de::Error,
70    {
71      Ok(Value {
72        kind: Some(Kind::NullValue(NullValue::NullValue as i32)),
73      })
74    }
75
76    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
77    where
78      E: de::Error,
79    {
80      Ok(Value {
81        kind: Some(Kind::BoolValue(v)),
82      })
83    }
84
85    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
86    where
87      E: de::Error,
88    {
89      Ok(Value {
90        kind: Some(Kind::NumberValue(v)),
91      })
92    }
93
94    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
95    where
96      E: de::Error,
97    {
98      Ok(Value {
99        kind: Some(Kind::StringValue(v)),
100      })
101    }
102
103    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
104    where
105      E: de::Error,
106    {
107      self.visit_string(v.to_owned())
108    }
109
110    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
111    where
112      A: MapAccess<'de>,
113    {
114      let s = Struct::deserialize(de::value::MapAccessDeserializer::new(map))?;
115      Ok(Value {
116        kind: Some(Kind::StructValue(s)),
117      })
118    }
119
120    fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
121    where
122      A: SeqAccess<'de>,
123    {
124      let l = ListValue::deserialize(de::value::SeqAccessDeserializer::new(seq))?;
125      Ok(Value {
126        kind: Some(Kind::ListValue(l)),
127      })
128    }
129  }
130
131  impl<'de> Deserialize<'de> for BytesValue {
132    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
133    where
134      D: Deserializer<'de>,
135    {
136      struct BytesValueVisitor;
137
138      impl<'de> Visitor<'de> for BytesValueVisitor {
139        type Value = BytesValue;
140
141        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
142          formatter.write_str("a base64 encoded string")
143        }
144
145        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
146        where
147          E: de::Error,
148        {
149          BASE64_STANDARD
150            .decode(v)
151            .map(|value| BytesValue {
152              value: Bytes::from(value),
153            })
154            .map_err(de::Error::custom)
155        }
156      }
157
158      deserializer.deserialize_str(BytesValueVisitor)
159    }
160  }
161}
162
163#[cfg(feature = "totokens")]
164mod totokens {
165  use proc_macro2::TokenStream;
166  use quote::{quote, ToTokens};
167
168  use crate::field_descriptor_proto::Type as ProtoType;
169
170  impl ToTokens for ProtoType {
171    fn to_tokens(&self, tokens: &mut TokenStream) {
172      let path = quote! { ::protocheck::types::field_descriptor_proto::Type };
173
174      match self {
175        ProtoType::Double => tokens.extend(quote! { #path::Double }),
176        ProtoType::Float => tokens.extend(quote! { #path::Float }),
177        ProtoType::Int64 => tokens.extend(quote! { #path::Int64 }),
178        ProtoType::Uint64 => tokens.extend(quote! { #path::Uint64 }),
179        ProtoType::Int32 => tokens.extend(quote! { #path::Int32 }),
180        ProtoType::Fixed64 => tokens.extend(quote! { #path::Fixed64 }),
181        ProtoType::Fixed32 => tokens.extend(quote! { #path::Fixed32 }),
182        ProtoType::Bool => tokens.extend(quote! { #path::Bool }),
183        ProtoType::String => tokens.extend(quote! { #path::String }),
184        ProtoType::Group => tokens.extend(quote! { #path::Group }),
185        ProtoType::Message => tokens.extend(quote! { #path::Message }),
186        ProtoType::Bytes => tokens.extend(quote! { #path::Bytes }),
187        ProtoType::Uint32 => tokens.extend(quote! { #path::Uint32 }),
188        ProtoType::Enum => tokens.extend(quote! { #path::Enum }),
189        ProtoType::Sfixed32 => tokens.extend(quote! { #path::Sfixed32 }),
190        ProtoType::Sfixed64 => tokens.extend(quote! { #path::Sfixed64 }),
191        ProtoType::Sint32 => tokens.extend(quote! { #path::Sint32 }),
192        ProtoType::Sint64 => tokens.extend(quote! { #path::Sint64 }),
193      }
194    }
195  }
196}