1#![allow(clippy::upper_case_acronyms)]
4
5use std::fmt;
6
7use glib::{value::ToValue, Date};
8use serde::{
9 de,
10 de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor},
11 ser,
12 ser::{Serialize, SerializeSeq, SerializeTuple, Serializer},
13};
14
15use crate::{
16 date_time_serde, value::*, value_serde::*, Buffer, DateTime, Sample, Structure, StructureRef,
17};
18
19struct FieldSe<'a>(&'a str, &'a glib::SendValue);
20impl Serialize for FieldSe<'_> {
21 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
22 ser_value!(self.1, |type_, value| {
23 let mut tup = serializer.serialize_tuple(3)?;
24 tup.serialize_element(self.0)?;
25 tup.serialize_element(type_)?;
26 tup.serialize_element(&value)?;
27 tup.end()
28 })
29 }
30}
31
32struct StructureForIter<'a>(&'a StructureRef);
33impl Serialize for StructureForIter<'_> {
34 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
35 let iter = self.0.iter();
36 let size = iter.size_hint().0;
37 if size > 0 {
38 let mut seq = serializer.serialize_seq(Some(size))?;
39 for field in iter {
40 seq.serialize_element(&FieldSe(field.0, field.1))?;
41 }
42 seq.end()
43 } else {
44 let seq = serializer.serialize_seq(None)?;
45 seq.end()
46 }
47 }
48}
49
50impl Serialize for StructureRef {
51 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
52 let mut tup = serializer.serialize_tuple(2)?;
53 tup.serialize_element(self.name().as_str())?;
54 tup.serialize_element(&StructureForIter(self))?;
55 tup.end()
56 }
57}
58
59impl Serialize for Structure {
60 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
61 <StructureRef as Serialize>::serialize(self.as_ref(), serializer)
62 }
63}
64
65struct FieldDe(String, SendValue);
66impl From<FieldDe> for (String, glib::SendValue) {
67 fn from(field_de: FieldDe) -> Self {
68 skip_assert_initialized!();
69 (field_de.0, field_de.1.into())
70 }
71}
72
73struct FieldVisitor;
74impl<'de> Visitor<'de> for FieldVisitor {
75 type Value = FieldDe;
76
77 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
78 formatter.write_str(
79 "a tuple of 3 elements (name: `String`, type name: `String`, value: `Value`)",
80 )
81 }
82
83 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
84 let name = seq
85 .next_element::<String>()?
86 .ok_or_else(|| de::Error::custom("Expected a value for `Value` name"))?;
87 let type_name = seq
88 .next_element::<String>()?
89 .ok_or_else(|| de::Error::custom("Expected a value for `Value` type"))?;
90 let send_value = de_send_value!(type_name, seq)?
91 .ok_or_else(|| de::Error::custom("Expected a value for `Value`"))?;
92 Ok(FieldDe(name, send_value))
93 }
94}
95
96impl<'de> Deserialize<'de> for FieldDe {
97 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
98 skip_assert_initialized!();
99 deserializer.deserialize_tuple(3, FieldVisitor)
100 }
101}
102
103struct FieldsDe<'a>(&'a mut StructureRef);
104
105struct FieldsVisitor<'a>(&'a mut StructureRef);
106impl<'de> Visitor<'de> for FieldsVisitor<'_> {
107 type Value = ();
108
109 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
110 formatter.write_str("a sequence of `Structure` `Field`s")
111 }
112
113 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<(), A::Error> {
114 while let Some(field) = seq.next_element::<FieldDe>()? {
115 let (name, value): (String, glib::SendValue) = field.into();
116 self.0.set_value(name.as_str(), value);
117 }
118
119 Ok(())
120 }
121}
122
123impl<'de> DeserializeSeed<'de> for FieldsDe<'_> {
124 type Value = ();
125
126 fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<(), D::Error> {
127 skip_assert_initialized!();
128 deserializer.deserialize_seq(FieldsVisitor(self.0))
129 }
130}
131
132struct StructureVisitor;
133impl<'de> Visitor<'de> for StructureVisitor {
134 type Value = Structure;
135
136 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
137 formatter.write_str("a `Structure` (name, sequence of `Field`s)")
138 }
139
140 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
141 let name = seq
142 .next_element::<String>()?
143 .ok_or_else(|| de::Error::custom("Expected a name for the `Structure`"))?;
144 let mut structure = Structure::new_empty(name);
145 seq.next_element_seed(FieldsDe(structure.as_mut()))?
146 .ok_or_else(|| de::Error::custom("Expected a sequence of `Field`s"))?;
147
148 Ok(structure)
149 }
150}
151
152impl<'de> Deserialize<'de> for Structure {
153 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
154 skip_assert_initialized!();
155 deserializer.deserialize_tuple(2, StructureVisitor)
156 }
157}
158
159#[cfg(test)]
160mod tests {
161 use glib::{Date, DateMonth};
162
163 use crate::{Array, DateTime, Fraction, Structure};
164
165 #[test]
166 fn test_serialize() {
167 crate::init().unwrap();
168
169 let s = Structure::builder("test")
170 .field("f1", "abc")
171 .field("f2", String::from("bcd"))
172 .field("f3", 123i32)
173 .field("fraction", Fraction::new(1, 2))
174 .field("date", Date::from_dmy(19, DateMonth::August, 2019).unwrap())
175 .field(
176 "date_time",
177 DateTime::new(2f32, 2019, 8, 19, 13, 34, 42f64).unwrap(),
178 )
179 .field("array", Array::new([1, 2]))
180 .build();
181
182 let pretty_config = ron::ser::PrettyConfig::new().new_line("".to_string());
183
184 let res = ron::ser::to_string_pretty(&s, pretty_config);
185 assert_eq!(
186 Ok(concat!(
187 r#"("test", ["#,
188 r#" ("f1", "String", Some("abc")),"#,
189 r#" ("f2", "String", Some("bcd")),"#,
190 r#" ("f3", "i32", 123),"#,
191 r#" ("fraction", "Fraction", (1, 2)),"#,
192 r#" ("date", "Date", Some(YMD(2019, 8, 19))),"#,
193 r#" ("date_time", "DateTime", Some(YMDhmsTz(2019, 8, 19, 13, 34, 42.0, 2.0))),"#,
194 r#" ("array", "Array", ["#,
195 r#" ("i32", 1),"#,
196 r#" ("i32", 2),"#,
197 r#" ]),"#,
198 r#"])"#,
199 )
200 .to_owned()),
201 res,
202 );
203 }
204
205 #[test]
206 fn test_deserialize() {
207 crate::init().unwrap();
208
209 let s_ron = r#"
210 ("test", [
211 ("f1", "String", Some("abc")),
212 ("f2", "String", Some("bcd")),
213 ("f3", "i32", 123),
214 ("fraction", "Fraction", (1, 2)),
215 ("date", "Date", Some(YMD(2019, 8, 19))),
216 ("date_time", "DateTime", Some(YMDhmsTz(2019, 8, 19, 13, 34, 42, 2))),
217 ("array", "Array", [
218 ("i32", 1),
219 ("i32", 2),
220 ]),
221 ])"#;
222 let s: Structure = ron::de::from_str(s_ron).unwrap();
223 assert_eq!(
224 s.as_ref(),
225 Structure::builder("test")
226 .field("f1", "abc")
227 .field("f2", "bcd")
228 .field("f3", 123)
229 .field("date", Date::from_dmy(19, DateMonth::August, 2019).unwrap())
230 .field(
231 "date_time",
232 DateTime::new(2f32, 2019, 8, 19, 13, 34, 42f64).unwrap()
233 )
234 .field("fraction", Fraction::new(1, 2))
235 .field("array", Array::new([1, 2]))
236 .build()
237 .as_ref()
238 );
239 }
240
241 #[test]
242 fn test_serde_roundtrip() {
243 crate::init().unwrap();
244
245 let s = Structure::builder("test")
246 .field("f1", "abc")
247 .field("f2", "bcd".to_owned())
248 .field("f3", 123i32)
249 .field("fraction", Fraction::new(1, 2))
250 .field("date", Date::from_dmy(19, DateMonth::August, 2019).unwrap())
251 .field(
252 "date_time",
253 DateTime::new(2f32, 2019, 8, 19, 13, 34, 42f64).unwrap(),
254 )
255 .field("array", Array::new([1, 2]))
256 .build();
257 let s_ser = ron::ser::to_string(&s).unwrap();
258 let s_de: Structure = ron::de::from_str(s_ser.as_str()).unwrap();
259 assert_eq!(s_de.as_ref(), s.as_ref());
260 }
261}