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