zvariant/
structure.rs

1#![allow(unknown_lints)]
2use serde::{
3    de::{DeserializeSeed, Deserializer, Error, SeqAccess, Visitor},
4    ser::{Serialize, SerializeTupleStruct, Serializer},
5};
6use std::fmt::{Display, Write};
7
8use crate::{
9    value::SignatureSeed, value_display_fmt, DynamicDeserialize, DynamicType, OwnedValue,
10    Signature, Value,
11};
12
13/// Use this to efficiently build a [`Structure`].
14///
15/// [`Structure`]: struct.Structure.html
16#[derive(Debug, Default, PartialEq)]
17pub struct StructureBuilder<'a>(Vec<Value<'a>>);
18
19impl<'a> StructureBuilder<'a> {
20    /// Create a new `StructureBuilder`.
21    ///
22    /// Same as `StructureBuilder::default()`.
23    pub fn new() -> Self {
24        Self::default()
25    }
26
27    /// Append `field` to `self`.
28    ///
29    /// This method returns `Self` so that you can use the builder pattern to create a complex
30    /// structure.
31    #[must_use]
32    pub fn add_field<T>(self, field: T) -> Self
33    where
34        T: DynamicType + Into<Value<'a>>,
35    {
36        self.append_field(Value::new(field))
37    }
38
39    /// Append `field` to `self`.
40    ///
41    /// Identical to `add_field`, except the field must be in the form of a `Value`.
42    #[must_use]
43    pub fn append_field<'e: 'a>(mut self, field: Value<'e>) -> Self {
44        self.0.push(field);
45
46        self
47    }
48
49    /// Append `field` to `self`.
50    ///
51    /// Identical to `add_field`, except it makes changes in-place.
52    pub fn push_field<T>(&mut self, field: T)
53    where
54        T: DynamicType + Into<Value<'a>>,
55    {
56        self.push_value(Value::new(field))
57    }
58
59    /// Append `field` to `self`.
60    ///
61    /// Identical to `append_field`, except it makes changes in-place.
62    pub fn push_value<'e: 'a>(&mut self, field: Value<'e>) {
63        self.0.push(field)
64    }
65
66    /// Build the `Structure`.
67    ///
68    /// [`Structure`]: struct.Structure.html
69    pub fn build(self) -> crate::Result<Structure<'a>> {
70        if self.0.is_empty() {
71            return Err(crate::Error::EmptyStructure);
72        }
73
74        let fields_signatures: Box<[Signature]> =
75            self.0.iter().map(Value::value_signature).cloned().collect();
76        let signature = Signature::structure(fields_signatures);
77
78        Ok(Structure {
79            fields: self.0,
80            signature,
81        })
82    }
83
84    /// Same as `build` except Signature is provided.
85    pub(crate) fn build_with_signature<'s: 'a>(self, signature: &Signature) -> Structure<'a> {
86        Structure {
87            fields: self.0,
88            signature: signature.clone(),
89        }
90    }
91}
92
93/// Use this to deserialize a [`Structure`].
94///
95/// The lifetime `'a` is now redundant and kept only for backward compatibility. All instances now
96/// has a `'static` lifetime. This will be removed in the next major release.
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub struct StructureSeed<'a> {
99    signature: Signature,
100    phantom: std::marker::PhantomData<&'a ()>,
101}
102
103impl StructureSeed<'static> {
104    /// Create a new `StructureSeed`
105    ///
106    /// The given signature must be a valid structure signature.
107    #[must_use]
108    pub fn new_unchecked(signature: &Signature) -> Self {
109        StructureSeed {
110            signature: signature.clone(),
111            phantom: std::marker::PhantomData,
112        }
113    }
114}
115
116impl TryFrom<Signature> for StructureSeed<'static> {
117    type Error = zvariant::Error;
118
119    fn try_from(signature: Signature) -> Result<Self, zvariant::Error> {
120        if !matches!(signature, Signature::Structure(_)) {
121            return Err(zvariant::Error::IncorrectType);
122        }
123
124        Ok(StructureSeed {
125            signature,
126            phantom: std::marker::PhantomData,
127        })
128    }
129}
130
131impl<'de> DeserializeSeed<'de> for StructureSeed<'_> {
132    type Value = Structure<'de>;
133    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
134    where
135        D: Deserializer<'de>,
136    {
137        deserializer.deserialize_seq(StructureVisitor {
138            signature: self.signature,
139        })
140    }
141}
142
143#[derive(Debug, Clone, PartialEq, Eq)]
144struct StructureVisitor {
145    signature: Signature,
146}
147
148impl<'de> Visitor<'de> for StructureVisitor {
149    type Value = Structure<'de>;
150
151    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
152        formatter.write_str("a Structure value")
153    }
154
155    fn visit_seq<V>(self, visitor: V) -> Result<Structure<'de>, V::Error>
156    where
157        V: SeqAccess<'de>,
158    {
159        SignatureSeed {
160            signature: &self.signature,
161        }
162        .visit_struct(visitor)
163    }
164}
165
166/// A helper type to wrap structs in [`Value`].
167///
168/// API is provided to convert from, and to tuples.
169///
170/// [`Value`]: enum.Value.html
171#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
172pub struct Structure<'a> {
173    fields: Vec<Value<'a>>,
174    signature: Signature,
175}
176
177impl<'a> Structure<'a> {
178    /// Get a reference to all the fields of `self`.
179    pub fn fields(&self) -> &[Value<'a>] {
180        &self.fields
181    }
182
183    /// Converts `self` to a `Vec` containing all its fields.
184    pub fn into_fields(self) -> Vec<Value<'a>> {
185        self.fields
186    }
187
188    /// Get the signature of this `Structure`.
189    pub fn signature(&self) -> &Signature {
190        &self.signature
191    }
192
193    pub(crate) fn try_to_owned(&self) -> crate::Result<Structure<'static>> {
194        Ok(Structure {
195            fields: self
196                .fields
197                .iter()
198                .map(|v| v.try_to_owned().map(Into::into))
199                .collect::<crate::Result<_>>()?,
200            signature: self.signature.to_owned(),
201        })
202    }
203
204    pub(crate) fn try_into_owned(self) -> crate::Result<Structure<'static>> {
205        Ok(Structure {
206            fields: self
207                .fields
208                .into_iter()
209                .map(|v| v.try_into_owned().map(Into::into))
210                .collect::<crate::Result<_>>()?,
211            signature: self.signature,
212        })
213    }
214
215    /// Attempt to clone `self`.
216    pub fn try_clone(&self) -> Result<Self, crate::Error> {
217        let fields = self
218            .fields
219            .iter()
220            .map(|v| v.try_clone())
221            .collect::<crate::Result<Vec<_>>>()?;
222
223        Ok(Self {
224            fields,
225            signature: self.signature.clone(),
226        })
227    }
228}
229
230impl Display for Structure<'_> {
231    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232        structure_display_fmt(self, f, true)
233    }
234}
235
236pub(crate) fn structure_display_fmt(
237    structure: &Structure<'_>,
238    f: &mut std::fmt::Formatter<'_>,
239    type_annotate: bool,
240) -> std::fmt::Result {
241    f.write_char('(')?;
242
243    let fields = structure.fields();
244
245    match fields.len() {
246        0 => {}
247        1 => {
248            value_display_fmt(&fields[0], f, type_annotate)?;
249            f.write_char(',')?;
250        }
251        _ => {
252            for (i, field) in fields.iter().enumerate() {
253                value_display_fmt(field, f, type_annotate)?;
254
255                if i + 1 < fields.len() {
256                    f.write_str(", ")?;
257                }
258            }
259        }
260    }
261
262    f.write_char(')')
263}
264
265impl DynamicType for Structure<'_> {
266    fn signature(&self) -> Signature {
267        self.signature.clone()
268    }
269}
270
271impl DynamicType for StructureSeed<'_> {
272    fn signature(&self) -> Signature {
273        self.signature.clone()
274    }
275}
276
277impl<'a> DynamicDeserialize<'a> for Structure<'a> {
278    type Deserializer = StructureSeed<'static>;
279
280    fn deserializer_for_signature(signature: &Signature) -> zvariant::Result<Self::Deserializer> {
281        let signature = match signature {
282            Signature::Structure(_) => signature.clone(),
283            s => Signature::structure([s.clone()]),
284        };
285
286        Ok(StructureSeed {
287            signature,
288            phantom: std::marker::PhantomData,
289        })
290    }
291}
292
293impl Serialize for Structure<'_> {
294    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
295    where
296        S: Serializer,
297    {
298        let mut structure = serializer.serialize_tuple_struct("Structure", self.fields.len())?;
299        for field in &self.fields {
300            field.serialize_value_as_tuple_struct_field(&mut structure)?;
301        }
302        structure.end()
303    }
304}
305
306macro_rules! tuple_impls {
307    ($($len:expr => ($($n:tt $name:ident)+))+) => {
308        $(
309            impl<'a, $($name),+> From<($($name),+,)> for Structure<'a>
310            where
311                $($name: DynamicType + Into<Value<'a>>,)+
312            {
313                #[inline]
314                fn from(value: ($($name),+,)) -> Self {
315                    StructureBuilder::new()
316                    $(
317                        .add_field(value. $n)
318                    )+
319                    .build().unwrap()
320                }
321            }
322
323            impl<'a, E, $($name),+> TryFrom<Structure<'a>> for ($($name),+,)
324            where
325                $($name: TryFrom<Value<'a>, Error = E>,)+
326                crate::Error: From<E>,
327
328            {
329                type Error = crate::Error;
330
331                fn try_from(mut s: Structure<'a>) -> core::result::Result<Self, Self::Error> {
332                    Ok((
333                    $(
334                         $name::try_from(s.fields.remove(0))?,
335                    )+
336                    ))
337                }
338            }
339
340            impl<'a, E, $($name),+> TryFrom<Value<'a>> for ($($name),+,)
341            where
342                $($name: TryFrom<Value<'a>, Error = E>,)+
343                crate::Error: From<E>,
344
345            {
346                type Error = crate::Error;
347
348                fn try_from(v: Value<'a>) -> core::result::Result<Self, Self::Error> {
349                    Self::try_from(Structure::try_from(v)?)
350                }
351            }
352
353            impl<E, $($name),+> TryFrom<OwnedValue> for ($($name),+,)
354            where
355                $($name: TryFrom<Value<'static>, Error = E>,)+
356                crate::Error: From<E>,
357
358            {
359                type Error = crate::Error;
360
361                fn try_from(v: OwnedValue) -> core::result::Result<Self, Self::Error> {
362                    Self::try_from(Value::from(v))
363                }
364            }
365        )+
366    }
367}
368
369tuple_impls! {
370    1 => (0 T0)
371    2 => (0 T0 1 T1)
372    3 => (0 T0 1 T1 2 T2)
373    4 => (0 T0 1 T1 2 T2 3 T3)
374    5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
375    6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
376    7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
377    8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
378    9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
379    10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
380    11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
381    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)
382    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)
383    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)
384    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)
385    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)
386}
387
388/// Owned [`Structure`]
389#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
390pub struct OwnedStructure(pub Structure<'static>);
391
392/// Use this to deserialize an [`OwnedStructure`].
393#[derive(Debug, Clone, PartialEq, Eq)]
394pub struct OwnedStructureSeed(Signature);
395
396impl DynamicType for OwnedStructure {
397    fn signature(&self) -> Signature {
398        self.0.signature().clone()
399    }
400}
401
402impl DynamicType for OwnedStructureSeed {
403    fn signature(&self) -> Signature {
404        self.0.clone()
405    }
406}
407
408impl DynamicDeserialize<'_> for OwnedStructure {
409    type Deserializer = OwnedStructureSeed;
410
411    fn deserializer_for_signature(signature: &Signature) -> zvariant::Result<Self::Deserializer> {
412        Structure::deserializer_for_signature(signature)
413            .map(|StructureSeed { signature, .. }| OwnedStructureSeed(signature))
414    }
415}
416
417impl<'de> DeserializeSeed<'de> for OwnedStructureSeed {
418    type Value = OwnedStructure;
419    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
420        deserializer
421            .deserialize_seq(StructureVisitor { signature: self.0 })
422            .and_then(|s| match s.try_to_owned() {
423                Ok(s) => Ok(OwnedStructure(s)),
424                Err(e) => Err(D::Error::custom(e)),
425            })
426    }
427}
428
429impl Serialize for OwnedStructure {
430    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
431    where
432        S: Serializer,
433    {
434        self.0.serialize(serializer)
435    }
436}