gstreamer/
serde_macros.rs
1#[macro_export]
4macro_rules! bitflags_serialize_impl {
5 ($type:ty, single_bit_flags$(, $feature:expr)?) => {
8 $(#[cfg(any(feature = $feature, docsrs))]
9 #[cfg_attr(docsrs, doc(cfg(feature = $feature)))])?
10 impl serde::Serialize for $type {
11 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
12 where
13 S: serde::Serializer,
14 {
15 let class = FlagsClass::with_type(Self::static_type()).unwrap();
16 let this = self.to_value();
17
18 let mut handled = Self::empty().to_value();
19 let mut res = String::new();
20
21 for v in class.values() {
22 let value = v.value();
23 if value.count_ones() == 1 && class.is_set(&this, value) && !class.is_set(&handled, value) {
24 if !res.is_empty() {
25 res.push('+');
26 }
27 res.push_str(v.nick());
28 handled = class.set(handled, value).expect("Failed to set flag");
29 }
30 }
31
32 serializer.serialize_str(&res)
33 }
34 }
35 };
36
37 ($type:ty, by_ones_decreasing$(, $feature:expr)?) => {
39 $(#[cfg(any(feature = $feature, docsrs))]
40 #[cfg_attr(docsrs, doc(cfg(feature = $feature)))])?
41 impl serde::Serialize for $type {
42 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
43 where
44 S: serde::Serializer,
45 {
46 let mut handled = Self::empty();
47 let mut res = String::new();
48
49 static SORTED_VALUES: std::sync::OnceLock<Vec<(u32, String)>> = std::sync::OnceLock::new();
50
51 let sorted_values = SORTED_VALUES.get_or_init(|| {
52 let class = FlagsClass::with_type(<$type>::static_type()).unwrap();
53 let mut sorted_values: Vec<(u32, String)> =
54 class.values().iter()
55 .map(|f| (f.value(), f.nick().to_owned()))
56 .collect();
57
58 sorted_values.sort_by(|(a, _), (b, _)| {
59 b.count_ones().cmp(&a.count_ones())
60 });
61
62 sorted_values
63 });
64
65 for (bits, nick) in sorted_values.iter() {
66 if let Some(value) = Self::from_bits(*bits) {
69 if !value.is_empty() && self.contains(value) && !handled.intersects(value) {
70 if !res.is_empty() {
71 res.push('+');
72 }
73 res.push_str(nick);
74 handled.insert(value);
75 }
76 }
77 }
78
79 serializer.serialize_str(&res)
80 }
81 }
82 };
83}
84
85#[macro_export]
86macro_rules! bitflags_deserialize_impl {
87 ($type:ty$(, $feature:expr)?) => {
88 $(#[cfg(any(feature = $feature, docsrs))]
89 #[cfg_attr(docsrs, doc(cfg(feature = $feature)))])?
90 impl<'de> serde::Deserialize<'de> for $type {
91 fn deserialize<D: serde::de::Deserializer<'de>>(
92 deserializer: D,
93 ) -> std::result::Result<Self, D::Error> {
94 skip_assert_initialized!();
95
96 struct FlagsVisitor;
97
98 impl<'de> serde::de::Visitor<'de> for FlagsVisitor {
99 type Value = $type;
100
101 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
102 formatter.write_str(
103 "one or more mask names separated by plus signs, or the empty string",
104 )
105 }
106
107 fn visit_str<E: serde::de::Error>(
108 self,
109 value: &str,
110 ) -> std::result::Result<Self::Value, E> {
111 if value.is_empty() {
112 return Ok(Self::Value::empty());
113 }
114
115 let mut gvalue = unsafe { glib::Value::from_type_unchecked(Self::Value::static_type()) };
116 let tokens = value.split('+');
117 let class = FlagsClass::with_type(Self::Value::static_type()).unwrap();
118
119 for token in tokens {
120 gvalue = class.set_by_nick(gvalue, token).map_err(|_| {
121 serde::de::Error::custom(&format!("Invalid value: {}", token))
122 })?;
123 }
124
125 Ok(unsafe {
126 from_glib(glib::gobject_ffi::g_value_get_flags(
127 gvalue.to_glib_none().0,
128 ))
129 })
130 }
131 }
132
133 deserializer.deserialize_str(FlagsVisitor)
134 }
135 }
136 };
137}
138
139#[macro_export]
140macro_rules! bitflags_serde_impl {
141 ($type:ty$(, $feature:expr)?) => {
142 $crate::bitflags_serialize_impl!($type, single_bit_flags$(, $feature)?);
143 $crate::bitflags_deserialize_impl!($type$(, $feature)?);
144 };
145}