1 // Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use serde::de;
10 use serde::de::{Deserialize, Deserializer, EnumAccess, SeqAccess, VariantAccess, Visitor};
11 use serde::ser::{Serialize, SerializeSeq, Serializer};
12 
13 use std::fmt;
14 
15 use CapsFeatures;
16 use CapsFeaturesRef;
17 
18 enum CapsFeaturesVariantKinds {
19     Any,
20     Some,
21 }
22 
23 const CAPS_FEATURES_VARIANT_ANY_ID: u32 = 0;
24 const CAPS_FEATURES_VARIANT_ANY_STR: &str = "Any";
25 const CAPS_FEATURES_VARIANT_SOME_ID: u32 = 1;
26 const CAPS_FEATURES_VARIANT_SOME_STR: &str = "Some";
27 
28 const CAPS_FEATURES_VARIANT_NAMES: &[&str] = &[
29     &CAPS_FEATURES_VARIANT_ANY_STR,
30     &CAPS_FEATURES_VARIANT_SOME_STR,
31 ];
32 
33 struct CapsFeaturesForIterSe<'a>(&'a CapsFeaturesRef);
34 impl<'a> Serialize for CapsFeaturesForIterSe<'a> {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>35     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
36         let iter = self.0.iter();
37         let size = iter.size_hint().0;
38         if size > 0 {
39             let mut seq = serializer.serialize_seq(Some(size))?;
40             for feature in iter {
41                 seq.serialize_element(feature)?;
42             }
43             seq.end()
44         } else {
45             let seq = serializer.serialize_seq(None)?;
46             seq.end()
47         }
48     }
49 }
50 
51 impl Serialize for CapsFeaturesRef {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>52     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
53         if self.is_any() {
54             serializer.serialize_unit_variant(
55                 stringify!(CapsFeatures),
56                 CAPS_FEATURES_VARIANT_ANY_ID,
57                 CAPS_FEATURES_VARIANT_ANY_STR,
58             )
59         } else {
60             serializer.serialize_newtype_variant(
61                 stringify!(CapsFeatures),
62                 CAPS_FEATURES_VARIANT_SOME_ID,
63                 CAPS_FEATURES_VARIANT_SOME_STR,
64                 &CapsFeaturesForIterSe(&self),
65             )
66         }
67     }
68 }
69 
70 impl Serialize for CapsFeatures {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>71     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
72         self.as_ref().serialize(serializer)
73     }
74 }
75 
76 struct CapsFeaturesSome(CapsFeatures);
77 
78 struct CapsFeaturesSomeVisitor;
79 impl<'de> Visitor<'de> for CapsFeaturesSomeVisitor {
80     type Value = CapsFeaturesSome;
81 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result82     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
83         formatter.write_str("a sequence of `&str`")
84     }
85 
visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error>86     fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
87         let mut features = CapsFeatures::new_empty();
88         while let Some(feature) = seq.next_element::<String>()? {
89             features.add(feature.as_ref());
90         }
91         Ok(CapsFeaturesSome(features))
92     }
93 }
94 
95 impl<'de> Deserialize<'de> for CapsFeaturesSome {
deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsFeaturesSome, D::Error>96     fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsFeaturesSome, D::Error> {
97         deserializer.deserialize_seq(CapsFeaturesSomeVisitor)
98     }
99 }
100 
101 struct CapsFeaturesVariantKindsVisitor;
102 impl<'de> Visitor<'de> for CapsFeaturesVariantKindsVisitor {
103     type Value = CapsFeaturesVariantKinds;
104 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result105     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
106         formatter.write_str("a Caps variant kind (`Any` or `Some`)")
107     }
108 
visit_u32<E: de::Error>(self, value: u32) -> Result<Self::Value, E>109     fn visit_u32<E: de::Error>(self, value: u32) -> Result<Self::Value, E> {
110         match value {
111             CAPS_FEATURES_VARIANT_ANY_ID => Ok(CapsFeaturesVariantKinds::Any),
112             CAPS_FEATURES_VARIANT_SOME_ID => Ok(CapsFeaturesVariantKinds::Some),
113             _ => Err(de::Error::invalid_value(
114                 de::Unexpected::Unsigned(u64::from(value)),
115                 &self,
116             )),
117         }
118     }
119 
visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E>120     fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
121         match value {
122             CAPS_FEATURES_VARIANT_ANY_STR => Ok(CapsFeaturesVariantKinds::Any),
123             CAPS_FEATURES_VARIANT_SOME_STR => Ok(CapsFeaturesVariantKinds::Some),
124             _ => Err(de::Error::unknown_variant(
125                 value,
126                 CAPS_FEATURES_VARIANT_NAMES,
127             )),
128         }
129     }
130 }
131 
132 impl<'de> Deserialize<'de> for CapsFeaturesVariantKinds {
deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>133     fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
134         deserializer.deserialize_identifier(CapsFeaturesVariantKindsVisitor)
135     }
136 }
137 
138 struct CapsFeaturesVisitor;
139 impl<'de> Visitor<'de> for CapsFeaturesVisitor {
140     type Value = CapsFeatures;
141 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result142     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
143         formatter.write_str("a CapsFeatures enum (`Any` or `Some()`)")
144     }
145 
visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error>146     fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
147         let res = match data.variant()? {
148             (CapsFeaturesVariantKinds::Any, _v) => CapsFeatures::new_any(),
149             (CapsFeaturesVariantKinds::Some, v) => v
150                 .newtype_variant::<CapsFeaturesSome>()
151                 .map(|caps_features_some| caps_features_some.0)?,
152         };
153 
154         Ok(res)
155     }
156 }
157 
158 impl<'de> Deserialize<'de> for CapsFeatures {
deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>159     fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
160         deserializer.deserialize_enum(
161             stringify!(Caps),
162             CAPS_FEATURES_VARIANT_NAMES,
163             CapsFeaturesVisitor,
164         )
165     }
166 }
167