1#![allow(unknown_lints)]
2use serde::{
3 de::{DeserializeSeed, Deserializer, Error, SeqAccess, Visitor},
4 ser::{Serialize, SerializeTupleStruct, Serializer},
5};
6use static_assertions::assert_impl_all;
7use std::fmt::{Display, Write};
8
9use crate::{
10 signature_parser::SignatureParser, value::SignatureSeed, value_display_fmt, DynamicDeserialize,
11 DynamicType, OwnedValue, Signature, Value,
12};
13
14#[derive(Debug, Default, PartialEq)]
18pub struct StructureBuilder<'a>(Vec<Value<'a>>);
19
20assert_impl_all!(StructureBuilder<'_>: Send, Sync, Unpin);
21
22impl<'a> StructureBuilder<'a> {
23 pub fn new() -> Self {
27 Self::default()
28 }
29
30 #[must_use]
35 pub fn add_field<T>(self, field: T) -> Self
36 where
37 T: DynamicType + Into<Value<'a>>,
38 {
39 self.append_field(Value::new(field))
40 }
41
42 #[must_use]
46 pub fn append_field<'e: 'a>(mut self, field: Value<'e>) -> Self {
47 self.0.push(field);
48
49 self
50 }
51
52 pub fn push_field<T>(&mut self, field: T)
56 where
57 T: DynamicType + Into<Value<'a>>,
58 {
59 self.push_value(Value::new(field))
60 }
61
62 pub fn push_value<'e: 'a>(&mut self, field: Value<'e>) {
66 self.0.push(field)
67 }
68
69 pub fn build(self) -> Structure<'a> {
73 let signature = create_signature_from_fields(&self.0);
74
75 Structure {
76 fields: self.0,
77 signature,
78 }
79 }
80
81 pub(crate) fn build_with_signature<'s: 'a>(self, signature: Signature<'s>) -> Structure<'a> {
83 Structure {
84 fields: self.0,
85 signature,
86 }
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq)]
94pub struct StructureSeed<'a>(Signature<'a>);
95
96assert_impl_all!(StructureSeed<'_>: Send, Sync, Unpin);
97
98impl<'a> StructureSeed<'a> {
99 #[must_use]
103 pub fn new_unchecked(signature: Signature<'a>) -> Self {
104 StructureSeed(signature)
105 }
106}
107
108impl<'a> TryFrom<Signature<'a>> for StructureSeed<'a> {
109 type Error = zvariant::Error;
110
111 fn try_from(signature: Signature<'a>) -> Result<Self, zvariant::Error> {
112 if signature.starts_with(zvariant::STRUCT_SIG_START_CHAR) {
113 Ok(StructureSeed(signature))
114 } else {
115 Err(zvariant::Error::IncorrectType)
116 }
117 }
118}
119
120impl<'de> DeserializeSeed<'de> for StructureSeed<'de> {
121 type Value = Structure<'de>;
122 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
123 where
124 D: Deserializer<'de>,
125 {
126 deserializer.deserialize_seq(StructureVisitor { signature: self.0 })
127 }
128}
129
130#[derive(Debug, Clone, PartialEq, Eq)]
131struct StructureVisitor<'a> {
132 signature: Signature<'a>,
133}
134
135impl<'de> Visitor<'de> for StructureVisitor<'de> {
136 type Value = Structure<'de>;
137
138 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139 formatter.write_str("a Structure value")
140 }
141
142 fn visit_seq<V>(self, visitor: V) -> Result<Structure<'de>, V::Error>
143 where
144 V: SeqAccess<'de>,
145 {
146 SignatureSeed {
147 signature: self.signature,
148 }
149 .visit_struct(visitor)
150 }
151}
152
153#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
159pub struct Structure<'a> {
160 fields: Vec<Value<'a>>,
161 signature: Signature<'a>,
162}
163
164assert_impl_all!(Structure<'_>: Send, Sync, Unpin);
165
166impl<'a> Structure<'a> {
167 pub fn fields(&self) -> &[Value<'a>] {
169 &self.fields
170 }
171
172 pub fn into_fields(self) -> Vec<Value<'a>> {
174 self.fields
175 }
176
177 pub fn signature(&self) -> Signature<'static> {
184 self.signature.to_owned()
185 }
186
187 pub fn full_signature(&self) -> &Signature<'_> {
189 &self.signature
190 }
191
192 pub(crate) fn try_to_owned(&self) -> crate::Result<Structure<'static>> {
193 Ok(Structure {
194 fields: self
195 .fields
196 .iter()
197 .map(|v| v.try_to_owned().map(Into::into))
198 .collect::<crate::Result<_>>()?,
199 signature: self.signature.to_owned(),
200 })
201 }
202
203 pub fn try_clone(&self) -> Result<Self, crate::Error> {
205 let fields = self
206 .fields
207 .iter()
208 .map(|v| v.try_clone())
209 .collect::<crate::Result<Vec<_>>>()?;
210
211 Ok(Self {
212 fields,
213 signature: self.signature.clone(),
214 })
215 }
216}
217
218impl Display for Structure<'_> {
219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220 structure_display_fmt(self, f, true)
221 }
222}
223
224pub(crate) fn structure_display_fmt(
225 structure: &Structure<'_>,
226 f: &mut std::fmt::Formatter<'_>,
227 type_annotate: bool,
228) -> std::fmt::Result {
229 f.write_char('(')?;
230
231 let fields = structure.fields();
232
233 match fields.len() {
234 0 => {}
235 1 => {
236 value_display_fmt(&fields[0], f, type_annotate)?;
237 f.write_char(',')?;
238 }
239 _ => {
240 for (i, field) in fields.iter().enumerate() {
241 value_display_fmt(field, f, type_annotate)?;
242
243 if i + 1 < fields.len() {
244 f.write_str(", ")?;
245 }
246 }
247 }
248 }
249
250 f.write_char(')')
251}
252
253impl<'a> Default for Structure<'a> {
254 fn default() -> Self {
255 let signature = Signature::from_static_str_unchecked("()");
256
257 Self {
258 fields: vec![],
259 signature,
260 }
261 }
262}
263
264impl<'a> DynamicType for Structure<'a> {
265 fn dynamic_signature(&self) -> Signature<'_> {
266 self.signature.as_ref()
267 }
268}
269
270impl<'a> DynamicType for StructureSeed<'a> {
271 fn dynamic_signature(&self) -> Signature<'_> {
272 self.0.as_ref()
273 }
274}
275
276impl<'a> DynamicDeserialize<'a> for Structure<'a> {
277 type Deserializer = StructureSeed<'a>;
278
279 fn deserializer_for_signature<S>(signature: S) -> zvariant::Result<Self::Deserializer>
280 where
281 S: TryInto<Signature<'a>>,
282 S::Error: Into<zvariant::Error>,
283 {
284 let mut signature = signature.try_into().map_err(Into::into)?;
285 if !signature.starts_with(zvariant::STRUCT_SIG_START_CHAR) {
286 signature = format!("({signature})").try_into()?;
288 return signature.try_into();
289 }
290
291 let mut parser = SignatureParser::new(signature.as_ref());
293 parser.parse_next_signature()?;
294 if !parser.done() {
295 signature = format!("({signature})").try_into()?;
297 }
298 signature.try_into()
299 }
300}
301
302impl<'a> Serialize for Structure<'a> {
303 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
304 where
305 S: Serializer,
306 {
307 let mut structure =
308 serializer.serialize_tuple_struct("zvariant::Structure", self.fields.len())?;
309 for field in &self.fields {
310 field.serialize_value_as_tuple_struct_field(&mut structure)?;
311 }
312 structure.end()
313 }
314}
315
316macro_rules! tuple_impls {
317 ($($len:expr => ($($n:tt $name:ident)+))+) => {
318 $(
319 impl<'a, $($name),+> From<($($name),+,)> for Structure<'a>
320 where
321 $($name: DynamicType + Into<Value<'a>>,)+
322 {
323 #[inline]
324 fn from(value: ($($name),+,)) -> Self {
325 StructureBuilder::new()
326 $(
327 .add_field(value. $n)
328 )+
329 .build()
330 }
331 }
332
333 impl<'a, E, $($name),+> TryFrom<Structure<'a>> for ($($name),+,)
334 where
335 $($name: TryFrom<Value<'a>, Error = E>,)+
336 crate::Error: From<E>,
337
338 {
339 type Error = crate::Error;
340
341 fn try_from(mut s: Structure<'a>) -> core::result::Result<Self, Self::Error> {
342 Ok((
343 $(
344 $name::try_from(s.fields.remove(0))?,
345 )+
346 ))
347 }
348 }
349
350 impl<'a, E, $($name),+> TryFrom<Value<'a>> for ($($name),+,)
351 where
352 $($name: TryFrom<Value<'a>, Error = E>,)+
353 crate::Error: From<E>,
354
355 {
356 type Error = crate::Error;
357
358 fn try_from(v: Value<'a>) -> core::result::Result<Self, Self::Error> {
359 Self::try_from(Structure::try_from(v)?)
360 }
361 }
362
363 impl<E, $($name),+> TryFrom<OwnedValue> for ($($name),+,)
364 where
365 $($name: TryFrom<Value<'static>, Error = E>,)+
366 crate::Error: From<E>,
367
368 {
369 type Error = crate::Error;
370
371 fn try_from(v: OwnedValue) -> core::result::Result<Self, Self::Error> {
372 Self::try_from(Value::from(v))
373 }
374 }
375 )+
376 }
377}
378
379tuple_impls! {
380 1 => (0 T0)
381 2 => (0 T0 1 T1)
382 3 => (0 T0 1 T1 2 T2)
383 4 => (0 T0 1 T1 2 T2 3 T3)
384 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
385 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
386 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
387 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
388 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
389 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
390 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
391 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
392 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
393 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
394 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
395 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
396}
397
398fn create_signature_from_fields(fields: &[Value<'_>]) -> Signature<'static> {
399 let mut signature = String::with_capacity(255);
400 signature.push('(');
401 for field in fields {
402 signature.push_str(&field.value_signature());
403 }
404 signature.push(')');
405
406 Signature::from_string_unchecked(signature)
407}
408
409#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
411pub struct OwnedStructure(pub Structure<'static>);
412
413#[derive(Debug, Clone, PartialEq, Eq)]
415pub struct OwnedStructureSeed(Signature<'static>);
416
417impl DynamicType for OwnedStructure {
418 fn dynamic_signature(&self) -> Signature<'_> {
419 self.0.dynamic_signature()
420 }
421}
422
423impl DynamicType for OwnedStructureSeed {
424 fn dynamic_signature(&self) -> Signature<'_> {
425 self.0.clone()
426 }
427}
428
429impl<'de> DynamicDeserialize<'de> for OwnedStructure {
430 type Deserializer = OwnedStructureSeed;
431
432 fn deserializer_for_signature<S>(signature: S) -> zvariant::Result<Self::Deserializer>
433 where
434 S: TryInto<Signature<'de>>,
435 S::Error: Into<zvariant::Error>,
436 {
437 Structure::deserializer_for_signature(signature)
438 .map(|StructureSeed(s)| OwnedStructureSeed(s.to_owned()))
439 }
440}
441
442impl<'de> DeserializeSeed<'de> for OwnedStructureSeed {
443 type Value = OwnedStructure;
444 fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
445 deserializer
446 .deserialize_seq(StructureVisitor { signature: self.0 })
447 .and_then(|s| match s.try_to_owned() {
448 Ok(s) => Ok(OwnedStructure(s)),
449 Err(e) => Err(D::Error::custom(e)),
450 })
451 }
452}
453
454impl Serialize for OwnedStructure {
455 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
456 where
457 S: Serializer,
458 {
459 self.0.serialize(serializer)
460 }
461}