zvariant/
value.rs

1use core::str;
2use std::{
3    convert::TryFrom,
4    fmt::{Display, Write},
5    marker::PhantomData,
6};
7
8use serde::{
9    de::{
10        Deserialize, DeserializeSeed, Deserializer, Error, MapAccess, SeqAccess, Unexpected,
11        Visitor,
12    },
13    ser::{Serialize, SerializeSeq, SerializeStruct, SerializeTupleStruct, Serializer},
14};
15use static_assertions::assert_impl_all;
16
17use crate::{
18    array_display_fmt, dict_display_fmt, signature_parser::SignatureParser, structure_display_fmt,
19    utils::*, Array, Basic, Dict, DynamicType, ObjectPath, OwnedValue, Signature, Str, Structure,
20    StructureBuilder, Type,
21};
22#[cfg(feature = "gvariant")]
23use crate::{maybe_display_fmt, Maybe};
24
25#[cfg(unix)]
26use crate::Fd;
27
28/// A generic container, in the form of an enum that holds exactly one value of any of the other
29/// types.
30///
31/// Note that this type corresponds to the `VARIANT` data type defined by the [D-Bus specification]
32/// and as such, its encoding is not the same as that of the enclosed value.
33///
34/// # Examples
35///
36/// ```
37/// use std::convert::TryFrom;
38/// use zvariant::{from_slice, to_bytes, EncodingContext, Value};
39///
40/// // Create a Value from an i16
41/// let v = Value::new(i16::max_value());
42///
43/// // Encode it
44/// let ctxt = EncodingContext::<byteorder::LE>::new_dbus(0);
45/// let encoding = to_bytes(ctxt, &v).unwrap();
46///
47/// // Decode it back
48/// let v: Value = from_slice(&encoding, ctxt).unwrap();
49///
50/// // Check everything is as expected
51/// assert_eq!(i16::try_from(&v).unwrap(), i16::max_value());
52/// ```
53///
54/// Now let's try a more complicated example:
55///
56/// ```
57/// use std::convert::TryFrom;
58/// use zvariant::{from_slice, to_bytes, EncodingContext};
59/// use zvariant::{Structure, Value, Str};
60///
61/// // Create a Value from a tuple this time
62/// let v = Value::new((i16::max_value(), "hello", true));
63///
64/// // Same drill as previous example
65/// let ctxt = EncodingContext::<byteorder::LE>::new_dbus(0);
66/// let encoding = to_bytes(ctxt, &v).unwrap();
67/// let v: Value = from_slice(&encoding, ctxt).unwrap();
68///
69/// // Check everything is as expected
70/// let s = Structure::try_from(v).unwrap();
71/// assert_eq!(
72///     <(i16, Str, bool)>::try_from(s).unwrap(),
73///     (i16::max_value(), Str::from("hello"), true),
74/// );
75/// ```
76///
77/// [D-Bus specification]: https://dbus.freedesktop.org/doc/dbus-specification.html#container-types
78#[derive(Debug, Clone, PartialEq)]
79pub enum Value<'a> {
80    // Simple types
81    U8(u8),
82    Bool(bool),
83    I16(i16),
84    U16(u16),
85    I32(i32),
86    U32(u32),
87    I64(i64),
88    U64(u64),
89    F64(f64),
90    Str(Str<'a>),
91    Signature(Signature<'a>),
92    ObjectPath(ObjectPath<'a>),
93    Value(Box<Value<'a>>),
94
95    // Container types
96    Array(Array<'a>),
97    Dict(Dict<'a, 'a>),
98    Structure(Structure<'a>),
99    #[cfg(feature = "gvariant")]
100    Maybe(Maybe<'a>),
101
102    #[cfg(unix)]
103    Fd(Fd),
104}
105
106assert_impl_all!(Value<'_>: Send, Sync, Unpin);
107
108macro_rules! serialize_value {
109    ($self:ident $serializer:ident.$method:ident $($first_arg:expr)*) => {
110        match $self {
111            Value::U8(value) => $serializer.$method($($first_arg,)* value),
112            Value::Bool(value) => $serializer.$method($($first_arg,)* value),
113            Value::I16(value) => $serializer.$method($($first_arg,)* value),
114            Value::U16(value) => $serializer.$method($($first_arg,)* value),
115            Value::I32(value) => $serializer.$method($($first_arg,)* value),
116            Value::U32(value) => $serializer.$method($($first_arg,)* value),
117            Value::I64(value) => $serializer.$method($($first_arg,)* value),
118            Value::U64(value) => $serializer.$method($($first_arg,)* value),
119            Value::F64(value) => $serializer.$method($($first_arg,)* value),
120            Value::Str(value) => $serializer.$method($($first_arg,)* value),
121            Value::Signature(value) => $serializer.$method($($first_arg,)* value),
122            Value::ObjectPath(value) => $serializer.$method($($first_arg,)* value),
123            Value::Value(value) => $serializer.$method($($first_arg,)* value),
124
125            // Container types
126            Value::Array(value) => $serializer.$method($($first_arg,)* value),
127            Value::Dict(value) => $serializer.$method($($first_arg,)* value),
128            Value::Structure(value) => $serializer.$method($($first_arg,)* value),
129            #[cfg(feature = "gvariant")]
130            Value::Maybe(value) => $serializer.$method($($first_arg,)* value),
131
132            #[cfg(unix)]
133            Value::Fd(value) => $serializer.$method($($first_arg,)* value),
134        }
135    }
136}
137
138impl<'a> Value<'a> {
139    /// Make a [`Value`] for a given value.
140    ///
141    /// In general, you can use [`Into`] trait on basic types, except
142    /// when you explicitly need to wrap [`Value`] itself, in which
143    /// case this constructor comes handy.
144    ///
145    /// # Examples
146    ///
147    /// ```
148    /// use zvariant::Value;
149    ///
150    /// let s = Value::new("hello");
151    /// let u: Value = 51.into();
152    /// assert_ne!(s, u);
153    /// ```
154    ///
155    /// [`Value`]: enum.Value.html
156    /// [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
157    pub fn new<T>(value: T) -> Self
158    where
159        T: Into<Self> + DynamicType,
160    {
161        // With specialization, we wouldn't have this
162        if value.dynamic_signature() == VARIANT_SIGNATURE_STR {
163            Self::Value(Box::new(value.into()))
164        } else {
165            value.into()
166        }
167    }
168
169    /// Create an owned version of `self`.
170    ///
171    /// Ideally, we should implement [`std::borrow::ToOwned`] trait for `Value`, but that's
172    /// implemented generically for us through `impl<T: Clone> ToOwned for T` and it's not what we
173    /// need/want.
174    pub fn to_owned(&self) -> OwnedValue {
175        OwnedValue(match self {
176            Value::U8(v) => Value::U8(*v),
177            Value::Bool(v) => Value::Bool(*v),
178            Value::I16(v) => Value::I16(*v),
179            Value::U16(v) => Value::U16(*v),
180            Value::I32(v) => Value::I32(*v),
181            Value::U32(v) => Value::U32(*v),
182            Value::I64(v) => Value::I64(*v),
183            Value::U64(v) => Value::U64(*v),
184            Value::F64(v) => Value::F64(*v),
185            Value::Str(v) => Value::Str(v.to_owned()),
186            Value::Signature(v) => Value::Signature(v.to_owned()),
187            Value::ObjectPath(v) => Value::ObjectPath(v.to_owned()),
188            Value::Value(v) => {
189                let o = OwnedValue::from(&**v);
190                Value::Value(Box::new(o.into_inner()))
191            }
192
193            Value::Array(v) => Value::Array(v.to_owned()),
194            Value::Dict(v) => Value::Dict(v.to_owned()),
195            Value::Structure(v) => Value::Structure(v.to_owned()),
196            #[cfg(feature = "gvariant")]
197            Value::Maybe(v) => Value::Maybe(v.to_owned()),
198            #[cfg(unix)]
199            Value::Fd(v) => Value::Fd(*v),
200        })
201    }
202
203    /// Get the signature of the enclosed value.
204    pub fn value_signature(&self) -> Signature<'_> {
205        match self {
206            Value::U8(_) => u8::signature(),
207            Value::Bool(_) => bool::signature(),
208            Value::I16(_) => i16::signature(),
209            Value::U16(_) => u16::signature(),
210            Value::I32(_) => i32::signature(),
211            Value::U32(_) => u32::signature(),
212            Value::I64(_) => i64::signature(),
213            Value::U64(_) => u64::signature(),
214            Value::F64(_) => f64::signature(),
215            Value::Str(_) => <&str>::signature(),
216            Value::Signature(_) => Signature::signature(),
217            Value::ObjectPath(_) => ObjectPath::signature(),
218            Value::Value(_) => Signature::from_static_str_unchecked("v"),
219
220            // Container types
221            Value::Array(value) => value.full_signature().clone(),
222            Value::Dict(value) => value.full_signature().clone(),
223            Value::Structure(value) => value.full_signature().clone(),
224            #[cfg(feature = "gvariant")]
225            Value::Maybe(value) => value.full_signature().clone(),
226
227            #[cfg(unix)]
228            Value::Fd(_) => Fd::signature(),
229        }
230    }
231
232    pub(crate) fn serialize_value_as_struct_field<S>(
233        &self,
234        name: &'static str,
235        serializer: &mut S,
236    ) -> Result<(), S::Error>
237    where
238        S: SerializeStruct,
239    {
240        serialize_value!(self serializer.serialize_field name)
241    }
242
243    pub(crate) fn serialize_value_as_tuple_struct_field<S>(
244        &self,
245        serializer: &mut S,
246    ) -> Result<(), S::Error>
247    where
248        S: SerializeTupleStruct,
249    {
250        serialize_value!(self serializer.serialize_field)
251    }
252
253    // Really crappy that we need to do this separately for struct and seq cases. :(
254    pub(crate) fn serialize_value_as_seq_element<S>(
255        &self,
256        serializer: &mut S,
257    ) -> Result<(), S::Error>
258    where
259        S: SerializeSeq,
260    {
261        serialize_value!(self serializer.serialize_element)
262    }
263
264    #[cfg(feature = "gvariant")]
265    pub(crate) fn serialize_value_as_some<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
266    where
267        S: Serializer,
268    {
269        serialize_value!(self serializer.serialize_some)
270    }
271
272    /// Try to get the underlying type `T`.
273    ///
274    /// Note that [`TryFrom<Value>`] is implemented for various types, and it's usually best to use
275    /// that instead. However, in generic code where you also want to unwrap [`Value::Value`],
276    /// you should use this function (because [`TryFrom<Value>`] can not be implemented for `Value`
277    /// itself as [`From<Value>`] is implicitly implemented for `Value`).
278    ///
279    /// # Examples
280    ///
281    /// ```
282    /// use std::convert::TryFrom;
283    /// use zvariant::{Result, Value};
284    ///
285    /// fn value_vec_to_type_vec<'a, T>(values: Vec<Value<'a>>) -> Result<Vec<T>>
286    /// where
287    ///     T: TryFrom<Value<'a>>,
288    /// {
289    ///     let mut res = vec![];
290    ///     for value in values.into_iter() {
291    ///         res.push(value.downcast().unwrap());
292    ///     }
293    ///
294    ///     Ok(res)
295    /// }
296    ///
297    /// // Let's try u32 values first
298    /// let v = vec![Value::U32(42), Value::U32(43)];
299    /// let v = value_vec_to_type_vec::<u32>(v).unwrap();
300    /// assert_eq!(v[0], 42);
301    /// assert_eq!(v[1], 43);
302    ///
303    /// // Now try Value values
304    /// let v = vec![Value::new(Value::U32(42)), Value::new(Value::U32(43))];
305    /// let v = value_vec_to_type_vec::<Value>(v).unwrap();
306    /// assert_eq!(v[0], Value::U32(42));
307    /// assert_eq!(v[1], Value::U32(43));
308    /// ```
309    ///
310    /// [`Value::Value`]: enum.Value.html#variant.Value
311    /// [`TryFrom<Value>`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html
312    /// [`From<Value>`]: https://doc.rust-lang.org/std/convert/trait.From.html
313    pub fn downcast<T: ?Sized>(self) -> Option<T>
314    where
315        T: TryFrom<Value<'a>>,
316    {
317        if let Value::Value(v) = self {
318            T::try_from(*v).ok()
319        } else {
320            T::try_from(self).ok()
321        }
322    }
323
324    /// Try to get a reference to the underlying type `T`.
325    ///
326    /// Same as [`downcast`] except it doesn't consume `self` and get a reference to the underlying
327    /// value.
328    ///
329    /// # Examples
330    ///
331    /// ```
332    /// use std::convert::TryFrom;
333    /// use zvariant::{Result, Value};
334    ///
335    /// fn value_vec_to_type_vec<'a, T>(values: &'a Vec<Value<'a>>) -> Result<Vec<&'a T>>
336    /// where
337    ///     &'a T: TryFrom<&'a Value<'a>>,
338    /// {
339    ///     let mut res = vec![];
340    ///     for value in values.into_iter() {
341    ///         res.push(value.downcast_ref().unwrap());
342    ///     }
343    ///
344    ///     Ok(res)
345    /// }
346    ///
347    /// // Let's try u32 values first
348    /// let v = vec![Value::U32(42), Value::U32(43)];
349    /// let v = value_vec_to_type_vec::<u32>(&v).unwrap();
350    /// assert_eq!(*v[0], 42);
351    /// assert_eq!(*v[1], 43);
352    ///
353    /// // Now try Value values
354    /// let v = vec![Value::new(Value::U32(42)), Value::new(Value::U32(43))];
355    /// let v = value_vec_to_type_vec::<Value>(&v).unwrap();
356    /// assert_eq!(*v[0], Value::U32(42));
357    /// assert_eq!(*v[1], Value::U32(43));
358    /// ```
359    ///
360    /// [`downcast`]: enum.Value.html#method.downcast
361    pub fn downcast_ref<T>(&'a self) -> Option<&'a T>
362    where
363        T: ?Sized,
364        &'a T: TryFrom<&'a Value<'a>>,
365    {
366        if let Value::Value(v) = self {
367            <&T>::try_from(v).ok()
368        } else {
369            <&T>::try_from(self).ok()
370        }
371    }
372}
373
374impl Display for Value<'_> {
375    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
376        value_display_fmt(self, f, true)
377    }
378}
379
380/// Implemented based on https://gitlab.gnome.org/GNOME/glib/-/blob/e1d47f0b0d0893ac9171e24cc7bf635495376546/glib/gvariant.c#L2213
381pub(crate) fn value_display_fmt(
382    value: &Value<'_>,
383    f: &mut std::fmt::Formatter<'_>,
384    type_annotate: bool,
385) -> std::fmt::Result {
386    match value {
387        Value::U8(num) => {
388            if type_annotate {
389                f.write_str("byte ")?;
390            }
391            write!(f, "0x{:02x}", num)
392        }
393        Value::Bool(boolean) => {
394            write!(f, "{}", boolean)
395        }
396        Value::I16(num) => {
397            if type_annotate {
398                f.write_str("int16 ")?;
399            }
400            write!(f, "{}", num)
401        }
402        Value::U16(num) => {
403            if type_annotate {
404                f.write_str("uint16 ")?;
405            }
406            write!(f, "{}", num)
407        }
408        Value::I32(num) => {
409            // Never annotate this type because it is the default for numbers
410            write!(f, "{}", num)
411        }
412        Value::U32(num) => {
413            if type_annotate {
414                f.write_str("uint32 ")?;
415            }
416            write!(f, "{}", num)
417        }
418        Value::I64(num) => {
419            if type_annotate {
420                f.write_str("int64 ")?;
421            }
422            write!(f, "{}", num)
423        }
424        Value::U64(num) => {
425            if type_annotate {
426                f.write_str("uint64 ")?;
427            }
428            write!(f, "{}", num)
429        }
430        Value::F64(num) => {
431            if num.fract() == 0. {
432                // Add a dot to make it clear that this is a float
433                write!(f, "{}.", num)
434            } else {
435                write!(f, "{}", num)
436            }
437        }
438        Value::Str(string) => {
439            write!(f, "{:?}", string.as_str())
440        }
441        Value::Signature(val) => {
442            if type_annotate {
443                f.write_str("signature ")?;
444            }
445            write!(f, "{:?}", val.as_str())
446        }
447        Value::ObjectPath(val) => {
448            if type_annotate {
449                f.write_str("objectpath ")?;
450            }
451            write!(f, "{:?}", val.as_str())
452        }
453        Value::Value(child) => {
454            f.write_char('<')?;
455
456            // Always annotate types in nested variants, because they are (by nature) of
457            // variable type.
458            value_display_fmt(child, f, true)?;
459
460            f.write_char('>')?;
461            Ok(())
462        }
463        Value::Array(array) => array_display_fmt(array, f, type_annotate),
464        Value::Dict(dict) => dict_display_fmt(dict, f, type_annotate),
465        Value::Structure(structure) => structure_display_fmt(structure, f, type_annotate),
466        #[cfg(feature = "gvariant")]
467        Value::Maybe(maybe) => maybe_display_fmt(maybe, f, type_annotate),
468        #[cfg(unix)]
469        Value::Fd(handle) => {
470            if type_annotate {
471                f.write_str("handle ")?;
472            }
473            write!(f, "{}", handle)
474        }
475    }
476}
477
478impl<'a> Serialize for Value<'a> {
479    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
480    where
481        S: Serializer,
482    {
483        // Serializer implementation needs to ensure padding isn't added for Value.
484        let mut structure = serializer.serialize_struct("zvariant::Value", 2)?;
485
486        let signature = self.value_signature();
487        structure.serialize_field("zvariant::Value::Signature", &signature)?;
488
489        self.serialize_value_as_struct_field("zvariant::Value::Value", &mut structure)?;
490
491        structure.end()
492    }
493}
494
495impl<'de: 'a, 'a> Deserialize<'de> for Value<'a> {
496    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
497    where
498        D: Deserializer<'de>,
499    {
500        let visitor = ValueVisitor;
501
502        deserializer.deserialize_any(visitor)
503    }
504}
505
506// Note that the Visitor implementations don't check for validity of the
507// signature. That's left to the Deserialize implementation of Signature
508// itself.
509
510struct ValueVisitor;
511
512impl<'de> Visitor<'de> for ValueVisitor {
513    type Value = Value<'de>;
514
515    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
516        formatter.write_str("a Value")
517    }
518
519    fn visit_seq<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
520    where
521        V: SeqAccess<'de>,
522    {
523        let signature = visitor.next_element::<Signature<'_>>()?.ok_or_else(|| {
524            Error::invalid_value(Unexpected::Other("nothing"), &"a Value signature")
525        })?;
526        let seed = ValueSeed::<Value<'_>> {
527            signature,
528            phantom: PhantomData,
529        };
530
531        visitor
532            .next_element_seed(seed)?
533            .ok_or_else(|| Error::invalid_value(Unexpected::Other("nothing"), &"a Value value"))
534    }
535
536    fn visit_map<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
537    where
538        V: MapAccess<'de>,
539    {
540        let (_, signature) = visitor
541            .next_entry::<&str, Signature<'_>>()?
542            .ok_or_else(|| {
543                Error::invalid_value(Unexpected::Other("nothing"), &"a Value signature")
544            })?;
545        let _ = visitor.next_key::<&str>()?;
546
547        let seed = ValueSeed::<Value<'_>> {
548            signature,
549            phantom: PhantomData,
550        };
551        visitor.next_value_seed(seed)
552    }
553}
554
555pub(crate) struct SignatureSeed<'de> {
556    pub signature: Signature<'de>,
557}
558
559impl<'de> SignatureSeed<'de> {
560    pub(crate) fn visit_array<V>(self, mut visitor: V) -> Result<Array<'de>, V::Error>
561    where
562        V: SeqAccess<'de>,
563    {
564        let element_signature = self.signature.slice(1..);
565        let mut array = Array::new_full_signature(self.signature.clone());
566
567        while let Some(elem) = visitor.next_element_seed(ValueSeed::<Value<'_>> {
568            signature: element_signature.clone(),
569            phantom: PhantomData,
570        })? {
571            elem.value_signature();
572            array.append(elem).map_err(Error::custom)?;
573        }
574
575        Ok(array)
576    }
577
578    pub(crate) fn visit_struct<V>(self, mut visitor: V) -> Result<Structure<'de>, V::Error>
579    where
580        V: SeqAccess<'de>,
581    {
582        let mut i = 1;
583        let signature_end = self.signature.len() - 1;
584        let mut builder = StructureBuilder::new();
585        while i < signature_end {
586            let fields_signature = self.signature.slice(i..signature_end);
587            let parser = SignatureParser::new(fields_signature.clone());
588            let len = parser.next_signature().map_err(Error::custom)?.len();
589            let field_signature = fields_signature.slice(0..len);
590            i += field_signature.len();
591
592            if let Some(field) = visitor.next_element_seed(ValueSeed::<Value<'_>> {
593                signature: field_signature,
594                phantom: PhantomData,
595            })? {
596                builder = builder.append_field(field);
597            }
598        }
599        Ok(builder.build_with_signature(self.signature))
600    }
601}
602
603impl<'de, T> From<ValueSeed<'de, T>> for SignatureSeed<'de> {
604    fn from(seed: ValueSeed<'de, T>) -> Self {
605        SignatureSeed {
606            signature: seed.signature,
607        }
608    }
609}
610
611struct ValueSeed<'de, T> {
612    signature: Signature<'de>,
613    phantom: PhantomData<T>,
614}
615
616impl<'de, T> ValueSeed<'de, T>
617where
618    T: Deserialize<'de>,
619{
620    #[inline]
621    fn visit_array<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
622    where
623        V: SeqAccess<'de>,
624    {
625        SignatureSeed::from(self)
626            .visit_array(visitor)
627            .map(Value::Array)
628    }
629
630    #[inline]
631    fn visit_struct<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
632    where
633        V: SeqAccess<'de>,
634    {
635        SignatureSeed::from(self)
636            .visit_struct(visitor)
637            .map(Value::Structure)
638    }
639
640    #[inline]
641    fn visit_variant<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
642    where
643        V: SeqAccess<'de>,
644    {
645        ValueVisitor
646            .visit_seq(visitor)
647            .map(|v| Value::Value(Box::new(v)))
648    }
649}
650
651macro_rules! value_seed_basic_method {
652    ($name:ident, $type:ty) => {
653        #[inline]
654        fn $name<E>(self, value: $type) -> Result<Value<'de>, E>
655        where
656            E: serde::de::Error,
657        {
658            Ok(value.into())
659        }
660    };
661}
662
663macro_rules! value_seed_str_method {
664    ($name:ident, $type:ty, $constructor:ident) => {
665        fn $name<E>(self, value: $type) -> Result<Value<'de>, E>
666        where
667            E: serde::de::Error,
668        {
669            match self.signature.as_str() {
670                <&str>::SIGNATURE_STR => Ok(Value::Str(Str::from(value))),
671                Signature::SIGNATURE_STR => Ok(Value::Signature(Signature::$constructor(value))),
672                ObjectPath::SIGNATURE_STR => Ok(Value::ObjectPath(ObjectPath::$constructor(value))),
673                _ => {
674                    let expected = format!(
675                        "`{}`, `{}` or `{}`",
676                        <&str>::SIGNATURE_STR,
677                        Signature::SIGNATURE_STR,
678                        ObjectPath::SIGNATURE_STR,
679                    );
680                    Err(Error::invalid_type(
681                        Unexpected::Str(self.signature.as_str()),
682                        &expected.as_str(),
683                    ))
684                }
685            }
686        }
687    };
688}
689
690impl<'de, T> Visitor<'de> for ValueSeed<'de, T>
691where
692    T: Deserialize<'de>,
693{
694    type Value = Value<'de>;
695
696    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
697        formatter.write_str("a Value value")
698    }
699
700    value_seed_basic_method!(visit_bool, bool);
701    value_seed_basic_method!(visit_i16, i16);
702    value_seed_basic_method!(visit_i64, i64);
703    value_seed_basic_method!(visit_u8, u8);
704    value_seed_basic_method!(visit_u16, u16);
705    value_seed_basic_method!(visit_u32, u32);
706    value_seed_basic_method!(visit_u64, u64);
707    value_seed_basic_method!(visit_f64, f64);
708
709    fn visit_i32<E>(self, value: i32) -> Result<Value<'de>, E>
710    where
711        E: serde::de::Error,
712    {
713        let v = match self.signature.as_bytes().first().ok_or_else(|| {
714            Error::invalid_value(
715                Unexpected::Other("nothing"),
716                &"i32 or fd signature character",
717            )
718        })? {
719            #[cfg(unix)]
720            b'h' => Fd::from(value).into(),
721            _ => value.into(),
722        };
723
724        Ok(v)
725    }
726
727    #[inline]
728    fn visit_str<E>(self, value: &str) -> Result<Value<'de>, E>
729    where
730        E: serde::de::Error,
731    {
732        self.visit_string(String::from(value))
733    }
734
735    value_seed_str_method!(visit_borrowed_str, &'de str, from_str_unchecked);
736
737    fn visit_seq<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
738    where
739        V: SeqAccess<'de>,
740    {
741        match self.signature.as_bytes().first().ok_or_else(|| {
742            Error::invalid_value(
743                Unexpected::Other("nothing"),
744                &"Array or Struct signature character",
745            )
746        })? {
747            // For some reason rustc doesn't like us using ARRAY_SIGNATURE_CHAR const
748            b'a' => self.visit_array(visitor),
749            b'(' => self.visit_struct(visitor),
750            b'v' => self.visit_variant(visitor),
751            b => Err(Error::invalid_value(
752                Unexpected::Char(*b as char),
753                &"a Value signature",
754            )),
755        }
756    }
757
758    fn visit_map<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
759    where
760        V: MapAccess<'de>,
761    {
762        if self.signature.len() < 5 {
763            return Err(serde::de::Error::invalid_length(
764                self.signature.len(),
765                &">= 5 characters in dict entry signature",
766            ));
767        }
768        let key_signature = self.signature.slice(2..3);
769        let signature_end = self.signature.len() - 1;
770        let value_signature = self.signature.slice(3..signature_end);
771        let mut dict = Dict::new_full_signature(self.signature.clone());
772
773        while let Some((key, value)) = visitor.next_entry_seed(
774            ValueSeed::<Value<'_>> {
775                signature: key_signature.clone(),
776                phantom: PhantomData,
777            },
778            ValueSeed::<Value<'_>> {
779                signature: value_signature.clone(),
780                phantom: PhantomData,
781            },
782        )? {
783            dict.append(key, value).map_err(Error::custom)?;
784        }
785
786        Ok(Value::Dict(dict))
787    }
788
789    #[cfg(feature = "gvariant")]
790    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
791    where
792        D: Deserializer<'de>,
793    {
794        let visitor = ValueSeed::<T> {
795            signature: self.signature.slice(1..),
796            phantom: PhantomData,
797        };
798
799        deserializer
800            .deserialize_any(visitor)
801            .map(|v| Value::Maybe(Maybe::just_full_signature(v, self.signature)))
802    }
803
804    #[cfg(not(feature = "gvariant"))]
805    fn visit_some<D>(self, _deserializer: D) -> Result<Self::Value, D::Error>
806    where
807        D: Deserializer<'de>,
808    {
809        panic!("`Maybe` type is only supported for GVariant format but it's disabled");
810    }
811
812    #[cfg(feature = "gvariant")]
813    fn visit_none<E>(self) -> Result<Self::Value, E>
814    where
815        E: Error,
816    {
817        let value = Maybe::nothing_full_signature(self.signature);
818
819        Ok(Value::Maybe(value))
820    }
821
822    #[cfg(not(feature = "gvariant"))]
823    fn visit_none<E>(self) -> Result<Self::Value, E>
824    where
825        E: Error,
826    {
827        panic!("`Maybe` type is only supported for GVariant format but it's disabled");
828    }
829}
830
831impl<'de, T> DeserializeSeed<'de> for ValueSeed<'de, T>
832where
833    T: Deserialize<'de>,
834{
835    type Value = Value<'de>;
836
837    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
838    where
839        D: Deserializer<'de>,
840    {
841        deserializer.deserialize_any(self)
842    }
843}
844
845impl<'a> Type for Value<'a> {
846    fn signature() -> Signature<'static> {
847        Signature::from_static_str_unchecked(VARIANT_SIGNATURE_STR)
848    }
849}
850
851#[cfg(test)]
852mod tests {
853    use std::collections::HashMap;
854
855    use super::*;
856
857    #[test]
858    fn value_display() {
859        assert_eq!(
860            Value::new((
861                255_u8,
862                true,
863                -1_i16,
864                65535_u16,
865                -1,
866                1_u32,
867                -9223372036854775808_i64,
868                18446744073709551615_u64,
869                (-1., 1.0, 11000000000., 1.1e-10)
870            ))
871            .to_string(),
872            "(byte 0xff, true, int16 -1, uint16 65535, -1, uint32 1, \
873                int64 -9223372036854775808, uint64 18446744073709551615, \
874                (-1., 1., 11000000000., 0.00000000011))"
875        );
876
877        assert_eq!(
878            Value::new(vec![
879                "", " ", "a", r#"""#, "'", "a'b", "a'\"b", "\\", "\n'\"",
880            ])
881            .to_string(),
882            r#"["", " ", "a", "\"", "'", "a'b", "a'\"b", "\\", "\n'\""]"#
883        );
884        assert_eq!(
885            Value::new(vec![
886                "\x07\x08\x09\x0A\x0B\x0C\x0D",
887                "\x7F",
888                char::from_u32(0xD8000).unwrap().to_string().as_str()
889            ])
890            .to_string(),
891            r#"["\u{7}\u{8}\t\n\u{b}\u{c}\r", "\u{7f}", "\u{d8000}"]"#
892        );
893
894        assert_eq!(
895            Value::new((
896                vec![
897                    Signature::from_static_str("").unwrap(),
898                    Signature::from_static_str("(ysa{sd})").unwrap(),
899                ],
900                vec![
901                    ObjectPath::from_static_str("/").unwrap(),
902                    ObjectPath::from_static_str("/a/very/looooooooooooooooooooooooo0000o0ng/path")
903                        .unwrap(),
904                ],
905                vec![
906                    Value::new(0_u8),
907                    Value::new((Value::new(51), Value::new(Value::new(1_u32)))),
908                ]
909            ))
910            .to_string(),
911            "([signature \"\", \"(ysa{sd})\"], \
912                [objectpath \"/\", \"/a/very/looooooooooooooooooooooooo0000o0ng/path\"], \
913                [<byte 0x00>, <(<51>, <<uint32 1>>)>])"
914        );
915
916        assert_eq!(Value::new(vec![] as Vec<Vec<i64>>).to_string(), "@aax []");
917        assert_eq!(
918            Value::new(vec![
919                vec![0_i16, 1_i16],
920                vec![2_i16, 3_i16],
921                vec![4_i16, 5_i16]
922            ])
923            .to_string(),
924            "[[int16 0, 1], [2, 3], [4, 5]]"
925        );
926        assert_eq!(
927            Value::new(vec![
928                b"Hello".to_vec(),
929                b"Hell\0o".to_vec(),
930                b"H\0ello\0".to_vec(),
931                b"Hello\0".to_vec(),
932                b"\0".to_vec(),
933                b" \0".to_vec(),
934                b"'\0".to_vec(),
935                b"\n'\"\0".to_vec(),
936                b"\\\0".to_vec(),
937            ])
938            .to_string(),
939            "[[byte 0x48, 0x65, 0x6c, 0x6c, 0x6f], \
940                [0x48, 0x65, 0x6c, 0x6c, 0x00, 0x6f], \
941                [0x48, 0x00, 0x65, 0x6c, 0x6c, 0x6f, 0x00], \
942                b\"Hello\", b\"\", b\" \", b\"'\", b\"\\n'\\\"\", b\"\\\\\"]"
943        );
944
945        assert_eq!(
946            Value::new(HashMap::<bool, bool>::new()).to_string(),
947            "@a{bb} {}"
948        );
949        assert_eq!(
950            Value::new(vec![(true, 0_i64)].into_iter().collect::<HashMap<_, _>>()).to_string(),
951            "{true: int64 0}",
952        );
953        // The order of the entries may vary
954        let val = Value::new(
955            vec![(32_u16, 64_i64), (100_u16, 200_i64)]
956                .into_iter()
957                .collect::<HashMap<_, _>>(),
958        )
959        .to_string();
960        assert!(val.starts_with('{'));
961        assert!(val.ends_with('}'));
962        assert_eq!(val.matches("uint16").count(), 1);
963        assert_eq!(val.matches("int64").count(), 1);
964
965        let items_str = val.split(", ").collect::<Vec<_>>();
966        assert_eq!(items_str.len(), 2);
967        assert!(items_str
968            .iter()
969            .any(|str| str.contains("32") && str.contains(": ") && str.contains("64")));
970        assert!(items_str
971            .iter()
972            .any(|str| str.contains("100") && str.contains(": ") && str.contains("200")));
973
974        assert_eq!(Value::new(Structure::default()).to_string(), "()");
975        assert_eq!(
976            Value::new(((true,), (true, false), (true, true, false))).to_string(),
977            "((true,), (true, false), (true, true, false))"
978        );
979
980        assert_eq!(
981            Value::new((
982                (Some(0_i16), Some(Some(0_i16)), Some(Some(Some(0_i16))),),
983                (None::<i16>, Some(None::<i16>), Some(Some(None::<i16>)),),
984                (None::<Option<i16>>, Some(None::<Option<i16>>)),
985            ))
986            .to_string(),
987            "((@mn 0, @mmn 0, @mmmn 0), \
988                (@mn nothing, @mmn just nothing, @mmmn just just nothing), \
989                (@mmn nothing, @mmmn just nothing))"
990        );
991
992        assert_eq!(
993            Value::new(vec![Fd::from(0), Fd::from(-100)]).to_string(),
994            "[handle 0, -100]"
995        );
996
997        assert_eq!(
998            Value::new((
999                None::<bool>,
1000                None::<bool>,
1001                Some(
1002                    vec![("size", Value::new((800, 600)))]
1003                        .into_iter()
1004                        .collect::<HashMap<_, _>>()
1005                ),
1006                vec![
1007                    Value::new(1),
1008                    Value::new(
1009                        vec![(
1010                            "dimension",
1011                            Value::new((
1012                                vec![2.4, 1.],
1013                                Some(Some(200_i16)),
1014                                Value::new((3_u8, "Hello!"))
1015                            ))
1016                        )]
1017                        .into_iter()
1018                        .collect::<HashMap<_, _>>()
1019                    )
1020                ],
1021                7777,
1022                ObjectPath::from_static_str("/").unwrap(),
1023                8888
1024            ))
1025            .to_string(),
1026            "(@mb nothing, @mb nothing, \
1027                @ma{sv} {\"size\": <(800, 600)>}, \
1028                [<1>, <{\"dimension\": <([2.4, 1.], \
1029                @mmn 200, <(byte 0x03, \"Hello!\")>)>}>], \
1030                7777, objectpath \"/\", 8888)"
1031        );
1032    }
1033}