oauth2/
helpers.rs

1use serde::ser::{Impossible, SerializeStructVariant, SerializeTupleVariant};
2use serde::{de, ser};
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::fmt;
5use std::marker::PhantomData;
6
7///
8/// Serde case-insensitive deserializer for an untagged `enum`.
9///
10/// This function converts values to lowercase before deserializing as the `enum`. Requires the
11/// `#[serde(rename_all = "lowercase")]` attribute to be set on the `enum`.
12///
13/// # Example
14///
15/// In example below, the following JSON values all deserialize to
16/// `GroceryBasket { fruit_item: Fruit::Banana }`:
17///
18///  * `{"fruit_item": "banana"}`
19///  * `{"fruit_item": "BANANA"}`
20///  * `{"fruit_item": "Banana"}`
21///
22/// Note: this example does not compile automatically due to
23/// [Rust issue #29286](https://github.com/rust-lang/rust/issues/29286).
24///
25/// ```
26/// # /*
27/// use serde::Deserialize;
28///
29/// #[derive(Deserialize)]
30/// #[serde(rename_all = "lowercase")]
31/// enum Fruit {
32///     Apple,
33///     Banana,
34///     Orange,
35/// }
36///
37/// #[derive(Deserialize)]
38/// struct GroceryBasket {
39///     #[serde(deserialize_with = "helpers::deserialize_untagged_enum_case_insensitive")]
40///     fruit_item: Fruit,
41/// }
42/// # */
43/// ```
44///
45pub fn deserialize_untagged_enum_case_insensitive<'de, T, D>(deserializer: D) -> Result<T, D::Error>
46where
47    T: Deserialize<'de>,
48    D: Deserializer<'de>,
49{
50    use serde::de::Error;
51    use serde_json::Value;
52    T::deserialize(Value::String(
53        String::deserialize(deserializer)?.to_lowercase(),
54    ))
55    .map_err(Error::custom)
56}
57
58///
59/// Serde space-delimited string deserializer for a `Vec<String>`.
60///
61/// This function splits a JSON string at each space character into a `Vec<String>` .
62///
63/// # Example
64///
65/// In example below, the JSON value `{"items": "foo bar baz"}` would deserialize to:
66///
67/// ```
68/// # struct GroceryBasket {
69/// #     items: Vec<String>,
70/// # }
71/// GroceryBasket {
72///     items: vec!["foo".to_string(), "bar".to_string(), "baz".to_string()]
73/// };
74/// ```
75///
76/// Note: this example does not compile automatically due to
77/// [Rust issue #29286](https://github.com/rust-lang/rust/issues/29286).
78///
79/// ```
80/// # /*
81/// use serde::Deserialize;
82///
83/// #[derive(Deserialize)]
84/// struct GroceryBasket {
85///     #[serde(deserialize_with = "helpers::deserialize_space_delimited_vec")]
86///     items: Vec<String>,
87/// }
88/// # */
89/// ```
90///
91pub fn deserialize_space_delimited_vec<'de, T, D>(deserializer: D) -> Result<T, D::Error>
92where
93    T: Default + Deserialize<'de>,
94    D: Deserializer<'de>,
95{
96    use serde::de::Error;
97    use serde_json::Value;
98    if let Some(space_delimited) = Option::<String>::deserialize(deserializer)? {
99        let entries = space_delimited
100            .split(' ')
101            .map(|s| Value::String(s.to_string()))
102            .collect();
103        T::deserialize(Value::Array(entries)).map_err(Error::custom)
104    } else {
105        // If the JSON value is null, use the default value.
106        Ok(T::default())
107    }
108}
109
110///
111/// Deserializes a string or array of strings into an array of strings
112///
113pub fn deserialize_optional_string_or_vec_string<'de, D>(
114    deserializer: D,
115) -> Result<Option<Vec<String>>, D::Error>
116where
117    D: Deserializer<'de>,
118{
119    struct StringOrVec(PhantomData<Vec<String>>);
120
121    impl<'de> de::Visitor<'de> for StringOrVec {
122        type Value = Option<Vec<String>>;
123
124        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
125            formatter.write_str("string or list of strings")
126        }
127
128        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
129        where
130            E: de::Error,
131        {
132            Ok(Some(vec![value.to_owned()]))
133        }
134
135        fn visit_none<E>(self) -> Result<Self::Value, E>
136        where
137            E: de::Error,
138        {
139            Ok(None)
140        }
141
142        fn visit_unit<E>(self) -> Result<Self::Value, E>
143        where
144            E: de::Error,
145        {
146            Ok(None)
147        }
148
149        fn visit_seq<S>(self, visitor: S) -> Result<Self::Value, S::Error>
150        where
151            S: de::SeqAccess<'de>,
152        {
153            Deserialize::deserialize(de::value::SeqAccessDeserializer::new(visitor)).map(Some)
154        }
155    }
156
157    deserializer.deserialize_any(StringOrVec(PhantomData))
158}
159
160///
161/// Serde space-delimited string serializer for an `Option<Vec<String>>`.
162///
163/// This function serializes a string vector into a single space-delimited string.
164/// If `string_vec_opt` is `None`, the function serializes it as `None` (e.g., `null`
165/// in the case of JSON serialization).
166///
167pub fn serialize_space_delimited_vec<T, S>(
168    vec_opt: &Option<Vec<T>>,
169    serializer: S,
170) -> Result<S::Ok, S::Error>
171where
172    T: AsRef<str>,
173    S: Serializer,
174{
175    if let Some(ref vec) = *vec_opt {
176        let space_delimited = vec.iter().map(|s| s.as_ref()).collect::<Vec<_>>().join(" ");
177
178        serializer.serialize_str(&space_delimited)
179    } else {
180        serializer.serialize_none()
181    }
182}
183
184///
185/// Serde string serializer for an enum.
186///<
187/// Source:
188/// [https://github.com/serde-rs/serde/issues/553](https://github.com/serde-rs/serde/issues/553)
189///
190pub fn variant_name<T: Serialize>(t: &T) -> &'static str {
191    #[derive(Debug)]
192    struct NotEnum;
193    type Result<T> = std::result::Result<T, NotEnum>;
194    impl std::error::Error for NotEnum {
195        fn description(&self) -> &str {
196            "not struct"
197        }
198    }
199    impl std::fmt::Display for NotEnum {
200        fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
201            unimplemented!()
202        }
203    }
204    impl ser::Error for NotEnum {
205        fn custom<T: std::fmt::Display>(_msg: T) -> Self {
206            NotEnum
207        }
208    }
209
210    struct VariantName;
211    impl Serializer for VariantName {
212        type Ok = &'static str;
213        type Error = NotEnum;
214        type SerializeSeq = Impossible<Self::Ok, Self::Error>;
215        type SerializeTuple = Impossible<Self::Ok, Self::Error>;
216        type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
217        type SerializeTupleVariant = Enum;
218        type SerializeMap = Impossible<Self::Ok, Self::Error>;
219        type SerializeStruct = Impossible<Self::Ok, Self::Error>;
220        type SerializeStructVariant = Enum;
221        fn serialize_bool(self, _v: bool) -> Result<Self::Ok> {
222            Err(NotEnum)
223        }
224        fn serialize_i8(self, _v: i8) -> Result<Self::Ok> {
225            Err(NotEnum)
226        }
227        fn serialize_i16(self, _v: i16) -> Result<Self::Ok> {
228            Err(NotEnum)
229        }
230        fn serialize_i32(self, _v: i32) -> Result<Self::Ok> {
231            Err(NotEnum)
232        }
233        fn serialize_i64(self, _v: i64) -> Result<Self::Ok> {
234            Err(NotEnum)
235        }
236        fn serialize_u8(self, _v: u8) -> Result<Self::Ok> {
237            Err(NotEnum)
238        }
239        fn serialize_u16(self, _v: u16) -> Result<Self::Ok> {
240            Err(NotEnum)
241        }
242        fn serialize_u32(self, _v: u32) -> Result<Self::Ok> {
243            Err(NotEnum)
244        }
245        fn serialize_u64(self, _v: u64) -> Result<Self::Ok> {
246            Err(NotEnum)
247        }
248        fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
249            Err(NotEnum)
250        }
251        fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
252            Err(NotEnum)
253        }
254        fn serialize_char(self, _v: char) -> Result<Self::Ok> {
255            Err(NotEnum)
256        }
257        fn serialize_str(self, _v: &str) -> Result<Self::Ok> {
258            Err(NotEnum)
259        }
260        fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
261            Err(NotEnum)
262        }
263        fn serialize_none(self) -> Result<Self::Ok> {
264            Err(NotEnum)
265        }
266        fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> Result<Self::Ok> {
267            Err(NotEnum)
268        }
269        fn serialize_unit(self) -> Result<Self::Ok> {
270            Err(NotEnum)
271        }
272        fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
273            Err(NotEnum)
274        }
275        fn serialize_unit_variant(
276            self,
277            _name: &'static str,
278            _variant_index: u32,
279            variant: &'static str,
280        ) -> Result<Self::Ok> {
281            Ok(variant)
282        }
283        fn serialize_newtype_struct<T: ?Sized + Serialize>(
284            self,
285            _name: &'static str,
286            _value: &T,
287        ) -> Result<Self::Ok> {
288            Err(NotEnum)
289        }
290        fn serialize_newtype_variant<T: ?Sized + Serialize>(
291            self,
292            _name: &'static str,
293            _variant_index: u32,
294            variant: &'static str,
295            _value: &T,
296        ) -> Result<Self::Ok> {
297            Ok(variant)
298        }
299        fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
300            Err(NotEnum)
301        }
302        fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
303            Err(NotEnum)
304        }
305        fn serialize_tuple_struct(
306            self,
307            _name: &'static str,
308            _len: usize,
309        ) -> Result<Self::SerializeTupleStruct> {
310            Err(NotEnum)
311        }
312        fn serialize_tuple_variant(
313            self,
314            _name: &'static str,
315            _variant_index: u32,
316            variant: &'static str,
317            _len: usize,
318        ) -> Result<Self::SerializeTupleVariant> {
319            Ok(Enum(variant))
320        }
321        fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
322            Err(NotEnum)
323        }
324        fn serialize_struct(
325            self,
326            _name: &'static str,
327            _len: usize,
328        ) -> Result<Self::SerializeStruct> {
329            Err(NotEnum)
330        }
331        fn serialize_struct_variant(
332            self,
333            _name: &'static str,
334            _variant_index: u32,
335            variant: &'static str,
336            _len: usize,
337        ) -> Result<Self::SerializeStructVariant> {
338            Ok(Enum(variant))
339        }
340    }
341
342    struct Enum(&'static str);
343    impl SerializeStructVariant for Enum {
344        type Ok = &'static str;
345        type Error = NotEnum;
346        fn serialize_field<T: ?Sized + Serialize>(
347            &mut self,
348            _key: &'static str,
349            _value: &T,
350        ) -> Result<()> {
351            Ok(())
352        }
353        fn end(self) -> Result<Self::Ok> {
354            Ok(self.0)
355        }
356    }
357    impl SerializeTupleVariant for Enum {
358        type Ok = &'static str;
359        type Error = NotEnum;
360        fn serialize_field<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<()> {
361            Ok(())
362        }
363        fn end(self) -> Result<Self::Ok> {
364            Ok(self.0)
365        }
366    }
367
368    t.serialize(VariantName).unwrap()
369}