1use core::{
2 cmp::Ordering,
3 fmt::{Display, Write},
4 hash::{Hash, Hasher},
5 marker::PhantomData,
6 mem::discriminant,
7 str,
8};
9
10use serde::{
11 de::{
12 Deserialize, DeserializeSeed, Deserializer, Error, MapAccess, SeqAccess, Unexpected,
13 Visitor,
14 },
15 ser::{
16 Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeTupleStruct, Serializer,
17 },
18};
19
20use crate::{
21 Array, Basic, Dict, DynamicType, ObjectPath, OwnedValue, Signature, Str, Structure,
22 StructureBuilder, Type, array_display_fmt, dict_display_fmt, structure_display_fmt, utils::*,
23};
24#[cfg(feature = "gvariant")]
25#[allow(deprecated)]
26use crate::{Maybe, maybe_display_fmt};
27
28#[cfg(unix)]
29use crate::Fd;
30
31#[derive(Debug, PartialEq, PartialOrd)]
80pub enum Value<'a> {
81 U8(u8),
83 Bool(bool),
84 I16(i16),
85 U16(u16),
86 I32(i32),
87 U32(u32),
88 I64(i64),
89 U64(u64),
90 F64(f64),
91 Str(Str<'a>),
92 Signature(Signature),
93 ObjectPath(ObjectPath<'a>),
94 Value(Box<Value<'a>>),
95
96 Array(Array<'a>),
98 Dict(Dict<'a, 'a>),
99 Structure(Structure<'a>),
100 #[cfg(feature = "gvariant")]
101 #[deprecated(
102 since = "5.15.0",
103 note = "GVariant support is deprecated and will be removed in zvariant 6.0. Use the \
104 `zgvariant` crate instead."
105 )]
106 #[allow(deprecated)]
107 Maybe(Maybe<'a>),
108
109 #[cfg(unix)]
110 Fd(Fd<'a>),
111}
112
113impl Hash for Value<'_> {
114 fn hash<H: Hasher>(&self, state: &mut H) {
115 discriminant(self).hash(state);
116 match self {
117 Self::U8(inner) => inner.hash(state),
118 Self::Bool(inner) => inner.hash(state),
119 Self::I16(inner) => inner.hash(state),
120 Self::U16(inner) => inner.hash(state),
121 Self::I32(inner) => inner.hash(state),
122 Self::U32(inner) => inner.hash(state),
123 Self::I64(inner) => inner.hash(state),
124 Self::U64(inner) => inner.hash(state),
125 Self::F64(inner) if *inner == 0. => 0f64.to_le_bytes().hash(state),
128 Self::F64(inner) => inner.to_le_bytes().hash(state),
129 Self::Str(inner) => inner.hash(state),
130 Self::Signature(inner) => inner.hash(state),
131 Self::ObjectPath(inner) => inner.hash(state),
132 Self::Value(inner) => inner.hash(state),
133 Self::Array(inner) => inner.hash(state),
134 Self::Dict(inner) => inner.hash(state),
135 Self::Structure(inner) => inner.hash(state),
136 #[cfg(feature = "gvariant")]
137 #[allow(deprecated)]
138 Self::Maybe(inner) => inner.hash(state),
139 #[cfg(unix)]
140 Self::Fd(inner) => inner.hash(state),
141 }
142 }
143}
144
145impl Eq for Value<'_> {}
146
147impl Ord for Value<'_> {
148 fn cmp(&self, other: &Self) -> Ordering {
149 self.partial_cmp(other)
150 .unwrap_or_else(|| match (self, other) {
151 (Self::F64(lhs), Self::F64(rhs)) => lhs.total_cmp(rhs),
152 _ => Ordering::Equal,
157 })
158 }
159}
160
161macro_rules! serialize_value {
162 ($self:ident $serializer:ident.$method:ident $($first_arg:expr)*) => {
163 match $self {
164 Value::U8(value) => $serializer.$method($($first_arg,)* value),
165 Value::Bool(value) => $serializer.$method($($first_arg,)* value),
166 Value::I16(value) => $serializer.$method($($first_arg,)* value),
167 Value::U16(value) => $serializer.$method($($first_arg,)* value),
168 Value::I32(value) => $serializer.$method($($first_arg,)* value),
169 Value::U32(value) => $serializer.$method($($first_arg,)* value),
170 Value::I64(value) => $serializer.$method($($first_arg,)* value),
171 Value::U64(value) => $serializer.$method($($first_arg,)* value),
172 Value::F64(value) => $serializer.$method($($first_arg,)* value),
173 Value::Str(value) => $serializer.$method($($first_arg,)* value),
174 Value::Signature(value) => $serializer.$method($($first_arg,)* value),
175 Value::ObjectPath(value) => $serializer.$method($($first_arg,)* value),
176 Value::Value(value) => $serializer.$method($($first_arg,)* value),
177
178 Value::Array(value) => $serializer.$method($($first_arg,)* value),
180 Value::Dict(value) => $serializer.$method($($first_arg,)* value),
181 Value::Structure(value) => $serializer.$method($($first_arg,)* value),
182 #[cfg(feature = "gvariant")]
183 #[allow(deprecated)]
184 Value::Maybe(value) => $serializer.$method($($first_arg,)* value),
185
186 #[cfg(unix)]
187 Value::Fd(value) => $serializer.$method($($first_arg,)* value),
188 }
189 }
190}
191
192impl<'a> Value<'a> {
193 pub fn new<T>(value: T) -> Self
212 where
213 T: Into<Self> + DynamicType,
214 {
215 if value.signature() == VARIANT_SIGNATURE_STR {
217 Self::Value(Box::new(value.into()))
218 } else {
219 value.into()
220 }
221 }
222
223 pub fn try_to_owned(&self) -> crate::Result<OwnedValue> {
230 Ok(OwnedValue(match self {
231 Value::U8(v) => Value::U8(*v),
232 Value::Bool(v) => Value::Bool(*v),
233 Value::I16(v) => Value::I16(*v),
234 Value::U16(v) => Value::U16(*v),
235 Value::I32(v) => Value::I32(*v),
236 Value::U32(v) => Value::U32(*v),
237 Value::I64(v) => Value::I64(*v),
238 Value::U64(v) => Value::U64(*v),
239 Value::F64(v) => Value::F64(*v),
240 Value::Str(v) => Value::Str(v.to_owned()),
241 Value::Signature(v) => Value::Signature(v.to_owned()),
242 Value::ObjectPath(v) => Value::ObjectPath(v.to_owned()),
243 Value::Value(v) => {
244 let o = OwnedValue::try_from(&**v)?;
245 Value::Value(Box::new(o.into_inner()))
246 }
247
248 Value::Array(v) => Value::Array(v.try_to_owned()?),
249 Value::Dict(v) => Value::Dict(v.try_to_owned()?),
250 Value::Structure(v) => Value::Structure(v.try_to_owned()?),
251 #[cfg(feature = "gvariant")]
252 #[allow(deprecated)]
253 Value::Maybe(v) => Value::Maybe(v.try_to_owned()?),
254 #[cfg(unix)]
255 Value::Fd(v) => Value::Fd(v.try_to_owned()?),
256 }))
257 }
258
259 pub fn try_into_owned(self) -> crate::Result<OwnedValue> {
267 Ok(OwnedValue(match self {
268 Value::U8(v) => Value::U8(v),
269 Value::Bool(v) => Value::Bool(v),
270 Value::I16(v) => Value::I16(v),
271 Value::U16(v) => Value::U16(v),
272 Value::I32(v) => Value::I32(v),
273 Value::U32(v) => Value::U32(v),
274 Value::I64(v) => Value::I64(v),
275 Value::U64(v) => Value::U64(v),
276 Value::F64(v) => Value::F64(v),
277 Value::Str(v) => Value::Str(v.into_owned()),
278 Value::Signature(v) => Value::Signature(v),
279 Value::ObjectPath(v) => Value::ObjectPath(v.into_owned()),
280 Value::Value(v) => Value::Value(Box::new(v.try_into_owned()?.into())),
281 Value::Array(v) => Value::Array(v.try_into_owned()?),
282 Value::Dict(v) => Value::Dict(v.try_into_owned()?),
283 Value::Structure(v) => Value::Structure(v.try_into_owned()?),
284 #[cfg(feature = "gvariant")]
285 #[allow(deprecated)]
286 Value::Maybe(v) => Value::Maybe(v.try_into_owned()?),
287 #[cfg(unix)]
288 Value::Fd(v) => Value::Fd(v.try_to_owned()?),
289 }))
290 }
291
292 pub fn value_signature(&self) -> &Signature {
294 match self {
295 Value::U8(_) => u8::SIGNATURE,
296 Value::Bool(_) => bool::SIGNATURE,
297 Value::I16(_) => i16::SIGNATURE,
298 Value::U16(_) => u16::SIGNATURE,
299 Value::I32(_) => i32::SIGNATURE,
300 Value::U32(_) => u32::SIGNATURE,
301 Value::I64(_) => i64::SIGNATURE,
302 Value::U64(_) => u64::SIGNATURE,
303 Value::F64(_) => f64::SIGNATURE,
304 Value::Str(_) => <&str>::SIGNATURE,
305 Value::Signature(_) => Signature::SIGNATURE,
306 Value::ObjectPath(_) => ObjectPath::SIGNATURE,
307 Value::Value(_) => &Signature::Variant,
308
309 Value::Array(value) => value.signature(),
311 Value::Dict(value) => value.signature(),
312 Value::Structure(value) => value.signature(),
313 #[cfg(feature = "gvariant")]
314 #[allow(deprecated)]
315 Value::Maybe(value) => value.signature(),
316
317 #[cfg(unix)]
318 Value::Fd(_) => Fd::SIGNATURE,
319 }
320 }
321
322 pub fn try_clone(&self) -> crate::Result<Self> {
330 Ok(match self {
331 Value::U8(v) => Value::U8(*v),
332 Value::Bool(v) => Value::Bool(*v),
333 Value::I16(v) => Value::I16(*v),
334 Value::U16(v) => Value::U16(*v),
335 Value::I32(v) => Value::I32(*v),
336 Value::U32(v) => Value::U32(*v),
337 Value::I64(v) => Value::I64(*v),
338 Value::U64(v) => Value::U64(*v),
339 Value::F64(v) => Value::F64(*v),
340 Value::Str(v) => Value::Str(v.clone()),
341 Value::Signature(v) => Value::Signature(v.clone()),
342 Value::ObjectPath(v) => Value::ObjectPath(v.clone()),
343 Value::Value(v) => Value::Value(Box::new(v.try_clone()?)),
344 Value::Array(v) => Value::Array(v.try_clone()?),
345 Value::Dict(v) => Value::Dict(v.try_clone()?),
346 Value::Structure(v) => Value::Structure(v.try_clone()?),
347 #[cfg(feature = "gvariant")]
348 #[allow(deprecated)]
349 Value::Maybe(v) => Value::Maybe(v.try_clone()?),
350 #[cfg(unix)]
351 Value::Fd(v) => Value::Fd(v.try_clone()?),
352 })
353 }
354
355 pub(crate) fn serialize_value_as_struct_field<S>(
356 &self,
357 name: &'static str,
358 serializer: &mut S,
359 ) -> Result<(), S::Error>
360 where
361 S: SerializeStruct,
362 {
363 serialize_value!(self serializer.serialize_field name)
364 }
365
366 pub(crate) fn serialize_value_as_tuple_struct_field<S>(
367 &self,
368 serializer: &mut S,
369 ) -> Result<(), S::Error>
370 where
371 S: SerializeTupleStruct,
372 {
373 serialize_value!(self serializer.serialize_field)
374 }
375
376 pub(crate) fn serialize_value_as_seq_element<S>(
378 &self,
379 serializer: &mut S,
380 ) -> Result<(), S::Error>
381 where
382 S: SerializeSeq,
383 {
384 serialize_value!(self serializer.serialize_element)
385 }
386
387 pub(crate) fn serialize_value_as_dict_key<S>(&self, serializer: &mut S) -> Result<(), S::Error>
388 where
389 S: SerializeMap,
390 {
391 serialize_value!(self serializer.serialize_key)
392 }
393
394 pub(crate) fn serialize_value_as_dict_value<S>(
395 &self,
396 serializer: &mut S,
397 ) -> Result<(), S::Error>
398 where
399 S: SerializeMap,
400 {
401 serialize_value!(self serializer.serialize_value)
402 }
403
404 #[cfg(feature = "gvariant")]
405 pub(crate) fn serialize_value_as_some<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
406 where
407 S: Serializer,
408 {
409 serialize_value!(self serializer.serialize_some)
410 }
411
412 pub fn downcast<T>(self) -> Result<T, crate::Error>
454 where
455 T: TryFrom<Value<'a>>,
456 <T as TryFrom<Value<'a>>>::Error: Into<crate::Error>,
457 {
458 if let Value::Value(v) = self {
459 T::try_from(*v)
460 } else {
461 T::try_from(self)
462 }
463 .map_err(Into::into)
464 }
465
466 pub fn downcast_ref<T>(&'a self) -> Result<T, crate::Error>
504 where
505 T: TryFrom<&'a Value<'a>>,
506 <T as TryFrom<&'a Value<'a>>>::Error: Into<crate::Error>,
507 {
508 if let Value::Value(v) = self {
509 <T>::try_from(v)
510 } else {
511 <T>::try_from(self)
512 }
513 .map_err(Into::into)
514 }
515}
516
517impl Display for Value<'_> {
518 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
519 value_display_fmt(self, f, true)
520 }
521}
522
523pub(crate) fn value_display_fmt(
525 value: &Value<'_>,
526 f: &mut std::fmt::Formatter<'_>,
527 type_annotate: bool,
528) -> std::fmt::Result {
529 match value {
530 Value::U8(num) => {
531 if type_annotate {
532 f.write_str("byte ")?;
533 }
534 write!(f, "0x{num:02x}")
535 }
536 Value::Bool(boolean) => {
537 write!(f, "{boolean}")
538 }
539 Value::I16(num) => {
540 if type_annotate {
541 f.write_str("int16 ")?;
542 }
543 write!(f, "{num}")
544 }
545 Value::U16(num) => {
546 if type_annotate {
547 f.write_str("uint16 ")?;
548 }
549 write!(f, "{num}")
550 }
551 Value::I32(num) => {
552 write!(f, "{num}")
554 }
555 Value::U32(num) => {
556 if type_annotate {
557 f.write_str("uint32 ")?;
558 }
559 write!(f, "{num}")
560 }
561 Value::I64(num) => {
562 if type_annotate {
563 f.write_str("int64 ")?;
564 }
565 write!(f, "{num}")
566 }
567 Value::U64(num) => {
568 if type_annotate {
569 f.write_str("uint64 ")?;
570 }
571 write!(f, "{num}")
572 }
573 Value::F64(num) => {
574 if num.fract() == 0. {
575 write!(f, "{num}.")
577 } else {
578 write!(f, "{num}")
579 }
580 }
581 Value::Str(string) => {
582 write!(f, "{:?}", string.as_str())
583 }
584 Value::Signature(val) => {
585 if type_annotate {
586 f.write_str("signature ")?;
587 }
588 write!(f, "{:?}", val.to_string())
589 }
590 Value::ObjectPath(val) => {
591 if type_annotate {
592 f.write_str("objectpath ")?;
593 }
594 write!(f, "{:?}", val.as_str())
595 }
596 Value::Value(child) => {
597 f.write_char('<')?;
598
599 value_display_fmt(child, f, true)?;
602
603 f.write_char('>')?;
604 Ok(())
605 }
606 Value::Array(array) => array_display_fmt(array, f, type_annotate),
607 Value::Dict(dict) => dict_display_fmt(dict, f, type_annotate),
608 Value::Structure(structure) => structure_display_fmt(structure, f, type_annotate),
609 #[cfg(feature = "gvariant")]
610 #[allow(deprecated)]
611 Value::Maybe(maybe) => maybe_display_fmt(maybe, f, type_annotate),
612 #[cfg(unix)]
613 Value::Fd(handle) => {
614 if type_annotate {
615 f.write_str("handle ")?;
616 }
617 write!(f, "{handle}")
618 }
619 }
620}
621
622impl Serialize for Value<'_> {
623 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
624 where
625 S: Serializer,
626 {
627 let mut structure = serializer.serialize_struct("Variant", 2)?;
629
630 let signature = self.value_signature();
631 structure.serialize_field("signature", &signature)?;
632
633 self.serialize_value_as_struct_field("value", &mut structure)?;
634
635 structure.end()
636 }
637}
638
639impl<'de: 'a, 'a> Deserialize<'de> for Value<'a> {
640 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
641 where
642 D: Deserializer<'de>,
643 {
644 let visitor = ValueVisitor;
645
646 deserializer.deserialize_any(visitor)
647 }
648}
649
650struct ValueVisitor;
651
652impl<'de> Visitor<'de> for ValueVisitor {
653 type Value = Value<'de>;
654
655 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
656 formatter.write_str("a Value")
657 }
658
659 fn visit_seq<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
660 where
661 V: SeqAccess<'de>,
662 {
663 let signature = visitor.next_element::<Signature>()?.ok_or_else(|| {
664 Error::invalid_value(Unexpected::Other("nothing"), &"a Value signature")
665 })?;
666 let seed = ValueSeed::<Value<'_>> {
667 signature: &signature,
668 phantom: PhantomData,
669 };
670
671 visitor
672 .next_element_seed(seed)?
673 .ok_or_else(|| Error::invalid_value(Unexpected::Other("nothing"), &"a Value value"))
674 }
675
676 fn visit_map<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
677 where
678 V: MapAccess<'de>,
679 {
680 let (_, signature) = visitor.next_entry::<&str, Signature>()?.ok_or_else(|| {
681 Error::invalid_value(Unexpected::Other("nothing"), &"a Value signature")
682 })?;
683 let _ = visitor.next_key::<&str>()?;
684
685 let seed = ValueSeed::<Value<'_>> {
686 signature: &signature,
687 phantom: PhantomData,
688 };
689 visitor.next_value_seed(seed)
690 }
691}
692
693pub(crate) struct SignatureSeed<'sig> {
694 pub signature: &'sig Signature,
695}
696
697impl SignatureSeed<'_> {
698 pub(crate) fn visit_array<'de, V>(self, mut visitor: V) -> Result<Array<'de>, V::Error>
699 where
700 V: SeqAccess<'de>,
701 {
702 let element_signature = match self.signature {
703 Signature::Array(child) => child.signature(),
704 _ => {
705 return Err(Error::invalid_type(
706 Unexpected::Str(&self.signature.to_string()),
707 &"an array signature",
708 ));
709 }
710 };
711 let mut array = Array::new_full_signature(self.signature);
712
713 while let Some(elem) = visitor.next_element_seed(ValueSeed::<Value<'_>> {
714 signature: element_signature,
715 phantom: PhantomData,
716 })? {
717 elem.value_signature();
718 array.append(elem).map_err(Error::custom)?;
719 }
720
721 Ok(array)
722 }
723
724 pub(crate) fn visit_struct<'de, V>(self, mut visitor: V) -> Result<Structure<'de>, V::Error>
725 where
726 V: SeqAccess<'de>,
727 {
728 let fields_signatures = match self.signature {
729 Signature::Structure(fields) => fields.iter(),
730 _ => {
731 return Err(Error::invalid_type(
732 Unexpected::Str(&self.signature.to_string()),
733 &"a structure signature",
734 ));
735 }
736 };
737
738 let mut builder = StructureBuilder::new();
739 for field_signature in fields_signatures {
740 if let Some(field) = visitor.next_element_seed(ValueSeed::<Value<'_>> {
741 signature: field_signature,
742 phantom: PhantomData,
743 })? {
744 builder = builder.append_field(field);
745 }
746 }
747 Ok(builder.build_with_signature(self.signature))
748 }
749}
750
751impl<'sig, T> From<ValueSeed<'sig, T>> for SignatureSeed<'sig> {
752 fn from(seed: ValueSeed<'sig, T>) -> Self {
753 SignatureSeed {
754 signature: seed.signature,
755 }
756 }
757}
758
759struct ValueSeed<'sig, T> {
760 signature: &'sig Signature,
761 phantom: PhantomData<T>,
762}
763
764impl<'de, T> ValueSeed<'_, T>
765where
766 T: Deserialize<'de>,
767{
768 #[inline]
769 fn visit_array<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
770 where
771 V: SeqAccess<'de>,
772 {
773 SignatureSeed::from(self)
774 .visit_array(visitor)
775 .map(Value::Array)
776 }
777
778 #[inline]
779 fn visit_struct<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
780 where
781 V: SeqAccess<'de>,
782 {
783 SignatureSeed::from(self)
784 .visit_struct(visitor)
785 .map(Value::Structure)
786 }
787
788 #[inline]
789 fn visit_variant_as_seq<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
790 where
791 V: SeqAccess<'de>,
792 {
793 ValueVisitor
794 .visit_seq(visitor)
795 .map(|v| Value::Value(Box::new(v)))
796 }
797
798 #[inline]
799 fn visit_variant_as_map<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
800 where
801 V: MapAccess<'de>,
802 {
803 ValueVisitor
804 .visit_map(visitor)
805 .map(|v| Value::Value(Box::new(v)))
806 }
807}
808
809macro_rules! value_seed_basic_method {
810 ($name:ident, $type:ty) => {
811 #[inline]
812 fn $name<E>(self, value: $type) -> Result<Value<'static>, E>
813 where
814 E: serde::de::Error,
815 {
816 Ok(value.into())
817 }
818 };
819}
820
821impl<'de, T> Visitor<'de> for ValueSeed<'_, T>
822where
823 T: Deserialize<'de>,
824{
825 type Value = Value<'de>;
826
827 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
828 formatter.write_str("a Value value")
829 }
830
831 value_seed_basic_method!(visit_bool, bool);
832 value_seed_basic_method!(visit_i16, i16);
833 value_seed_basic_method!(visit_i64, i64);
834 value_seed_basic_method!(visit_u8, u8);
835 value_seed_basic_method!(visit_u16, u16);
836 value_seed_basic_method!(visit_u32, u32);
837 value_seed_basic_method!(visit_u64, u64);
838 value_seed_basic_method!(visit_f64, f64);
839
840 fn visit_i32<E>(self, value: i32) -> Result<Value<'de>, E>
841 where
842 E: serde::de::Error,
843 {
844 let v = match &self.signature {
845 #[cfg(unix)]
846 Signature::Fd => {
847 debug_assert!(value >= 0);
848 let fd = unsafe { std::os::fd::BorrowedFd::borrow_raw(value) };
850 Fd::Borrowed(fd).into()
851 }
852 _ => value.into(),
853 };
854
855 Ok(v)
856 }
857
858 #[inline]
859 fn visit_str<E>(self, value: &str) -> Result<Value<'de>, E>
860 where
861 E: serde::de::Error,
862 {
863 self.visit_string(String::from(value))
864 }
865
866 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
867 where
868 E: Error,
869 {
870 match &self.signature {
871 Signature::Str => Ok(Value::Str(Str::from(v))),
872 Signature::Signature => Signature::try_from(v)
873 .map(Value::Signature)
874 .map_err(Error::custom),
875 Signature::ObjectPath => Ok(Value::ObjectPath(ObjectPath::from_str_unchecked(v))),
876 _ => {
877 let expected = format!(
878 "`{}`, `{}` or `{}`",
879 <&str>::SIGNATURE_STR,
880 Signature::SIGNATURE_STR,
881 ObjectPath::SIGNATURE_STR,
882 );
883 Err(Error::invalid_type(
884 Unexpected::Str(&self.signature.to_string()),
885 &expected.as_str(),
886 ))
887 }
888 }
889 }
890
891 fn visit_seq<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
892 where
893 V: SeqAccess<'de>,
894 {
895 match &self.signature {
896 Signature::Array(_) => self.visit_array(visitor),
898 Signature::Structure(_) => self.visit_struct(visitor),
899 Signature::Variant => self.visit_variant_as_seq(visitor),
900 s => Err(Error::invalid_value(
901 Unexpected::Str(&s.to_string()),
902 &"a Value signature",
903 )),
904 }
905 }
906
907 fn visit_map<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
908 where
909 V: MapAccess<'de>,
910 {
911 let (key_signature, value_signature) = match &self.signature {
912 Signature::Dict { key, value } => (key.signature().clone(), value.signature().clone()),
913 Signature::Variant => return self.visit_variant_as_map(visitor),
914 _ => {
915 return Err(Error::invalid_type(
916 Unexpected::Str(&self.signature.to_string()),
917 &"a dict signature",
918 ));
919 }
920 };
921
922 let mut dict = Dict::new_full_signature(self.signature);
923
924 while let Some((key, value)) = visitor.next_entry_seed(
925 ValueSeed::<Value<'_>> {
926 signature: &key_signature,
927 phantom: PhantomData,
928 },
929 ValueSeed::<Value<'_>> {
930 signature: &value_signature,
931 phantom: PhantomData,
932 },
933 )? {
934 dict.append(key, value).map_err(Error::custom)?;
935 }
936
937 Ok(Value::Dict(dict))
938 }
939
940 #[cfg(feature = "gvariant")]
941 #[allow(deprecated)]
942 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
943 where
944 D: Deserializer<'de>,
945 {
946 let child_signature = match &self.signature {
947 Signature::Maybe(child) => child.signature().clone(),
948 _ => {
949 return Err(Error::invalid_type(
950 Unexpected::Str(&self.signature.to_string()),
951 &"a maybe signature",
952 ));
953 }
954 };
955 let visitor = ValueSeed::<T> {
956 signature: &child_signature,
957 phantom: PhantomData,
958 };
959
960 deserializer
961 .deserialize_any(visitor)
962 .map(|v| Value::Maybe(Maybe::just_full_signature(v, self.signature)))
963 }
964
965 #[cfg(not(feature = "gvariant"))]
966 fn visit_some<D>(self, _deserializer: D) -> Result<Self::Value, D::Error>
967 where
968 D: Deserializer<'de>,
969 {
970 panic!("`Maybe` type is only supported for GVariant format but it's disabled");
971 }
972
973 #[cfg(feature = "gvariant")]
974 #[allow(deprecated)]
975 fn visit_none<E>(self) -> Result<Self::Value, E>
976 where
977 E: Error,
978 {
979 let value = Maybe::nothing_full_signature(self.signature);
980
981 Ok(Value::Maybe(value))
982 }
983
984 #[cfg(not(feature = "gvariant"))]
985 fn visit_none<E>(self) -> Result<Self::Value, E>
986 where
987 E: Error,
988 {
989 panic!("`Maybe` type is only supported for GVariant format but it's disabled");
990 }
991}
992
993impl<'de, T> DeserializeSeed<'de> for ValueSeed<'_, T>
994where
995 T: Deserialize<'de>,
996{
997 type Value = Value<'de>;
998
999 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1000 where
1001 D: Deserializer<'de>,
1002 {
1003 deserializer.deserialize_any(self)
1004 }
1005}
1006
1007impl Type for Value<'_> {
1008 const SIGNATURE: &'static Signature = &Signature::Variant;
1009}
1010
1011impl<'a> TryFrom<&Value<'a>> for Value<'a> {
1012 type Error = crate::Error;
1013
1014 fn try_from(value: &Value<'a>) -> crate::Result<Value<'a>> {
1015 value.try_clone()
1016 }
1017}
1018
1019impl Clone for Value<'_> {
1020 fn clone(&self) -> Self {
1028 self.try_clone()
1029 .expect("Process exceeded limit on maximum number of open file descriptors")
1030 }
1031}
1032
1033#[cfg(test)]
1034mod tests {
1035 use std::collections::HashMap;
1036
1037 use super::*;
1038
1039 #[test]
1040 fn value_display() {
1041 assert_eq!(
1042 Value::new((
1043 255_u8,
1044 true,
1045 -1_i16,
1046 65535_u16,
1047 -1,
1048 1_u32,
1049 -9223372036854775808_i64,
1050 18446744073709551615_u64,
1051 (-1., 1.0, 11000000000., 1.1e-10)
1052 ))
1053 .to_string(),
1054 "(byte 0xff, true, int16 -1, uint16 65535, -1, uint32 1, \
1055 int64 -9223372036854775808, uint64 18446744073709551615, \
1056 (-1., 1., 11000000000., 0.00000000011))"
1057 );
1058
1059 assert_eq!(
1060 Value::new(vec![
1061 "", " ", "a", r#"""#, "'", "a'b", "a'\"b", "\\", "\n'\"",
1062 ])
1063 .to_string(),
1064 r#"["", " ", "a", "\"", "'", "a'b", "a'\"b", "\\", "\n'\""]"#
1065 );
1066 assert_eq!(
1067 Value::new(vec![
1068 "\x07\x08\x09\x0A\x0B\x0C\x0D",
1069 "\x7F",
1070 char::from_u32(0xD8000).unwrap().to_string().as_str()
1071 ])
1072 .to_string(),
1073 r#"["\u{7}\u{8}\t\n\u{b}\u{c}\r", "\u{7f}", "\u{d8000}"]"#
1074 );
1075
1076 assert_eq!(
1077 Value::new((
1078 vec![crate::signature!(""), crate::signature!("(ysa{sd})"),],
1079 vec![
1080 ObjectPath::from_static_str("/").unwrap(),
1081 ObjectPath::from_static_str("/a/very/looooooooooooooooooooooooo0000o0ng/path")
1082 .unwrap(),
1083 ],
1084 vec![
1085 Value::new(0_u8),
1086 Value::new((Value::new(51), Value::new(Value::new(1_u32)))),
1087 ]
1088 ))
1089 .to_string(),
1090 "([signature \"\", \"(ysa{sd})\"], \
1091 [objectpath \"/\", \"/a/very/looooooooooooooooooooooooo0000o0ng/path\"], \
1092 [<byte 0x00>, <(<51>, <<uint32 1>>)>])"
1093 );
1094
1095 assert_eq!(Value::new(vec![] as Vec<Vec<i64>>).to_string(), "@aax []");
1096 assert_eq!(
1097 Value::new(vec![
1098 vec![0_i16, 1_i16],
1099 vec![2_i16, 3_i16],
1100 vec![4_i16, 5_i16]
1101 ])
1102 .to_string(),
1103 "[[int16 0, 1], [2, 3], [4, 5]]"
1104 );
1105 assert_eq!(
1106 Value::new(vec![
1107 b"Hello".to_vec(),
1108 b"Hell\0o".to_vec(),
1109 b"H\0ello\0".to_vec(),
1110 b"Hello\0".to_vec(),
1111 b"\0".to_vec(),
1112 b" \0".to_vec(),
1113 b"'\0".to_vec(),
1114 b"\n'\"\0".to_vec(),
1115 b"\\\0".to_vec(),
1116 ])
1117 .to_string(),
1118 "[[byte 0x48, 0x65, 0x6c, 0x6c, 0x6f], \
1119 [0x48, 0x65, 0x6c, 0x6c, 0x00, 0x6f], \
1120 [0x48, 0x00, 0x65, 0x6c, 0x6c, 0x6f, 0x00], \
1121 b\"Hello\", b\"\", b\" \", b\"'\", b\"\\n'\\\"\", b\"\\\\\"]"
1122 );
1123
1124 assert_eq!(
1125 Value::new(HashMap::<bool, bool>::new()).to_string(),
1126 "@a{bb} {}"
1127 );
1128 assert_eq!(
1129 Value::new(vec![(true, 0_i64)].into_iter().collect::<HashMap<_, _>>()).to_string(),
1130 "{true: int64 0}",
1131 );
1132 let val = Value::new(
1134 vec![(32_u16, 64_i64), (100_u16, 200_i64)]
1135 .into_iter()
1136 .collect::<HashMap<_, _>>(),
1137 )
1138 .to_string();
1139 assert!(val.starts_with('{'));
1140 assert!(val.ends_with('}'));
1141 assert_eq!(val.matches("uint16").count(), 1);
1142 assert_eq!(val.matches("int64").count(), 1);
1143
1144 let items_str = val.split(", ").collect::<Vec<_>>();
1145 assert_eq!(items_str.len(), 2);
1146 assert!(
1147 items_str
1148 .iter()
1149 .any(|str| str.contains("32") && str.contains(": ") && str.contains("64"))
1150 );
1151 assert!(
1152 items_str
1153 .iter()
1154 .any(|str| str.contains("100") && str.contains(": ") && str.contains("200"))
1155 );
1156
1157 assert_eq!(
1158 Value::new(((true,), (true, false), (true, true, false))).to_string(),
1159 "((true,), (true, false), (true, true, false))"
1160 );
1161
1162 #[cfg(any(feature = "gvariant", feature = "option-as-array"))]
1163 {
1164 #[cfg(unix)]
1165 use std::os::fd::BorrowedFd;
1166
1167 #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1168 let s = "((@mn 0, @mmn 0, @mmmn 0), \
1169 (@mn nothing, @mmn just nothing, @mmmn just just nothing), \
1170 (@mmn nothing, @mmmn just nothing))";
1171 #[cfg(feature = "option-as-array")]
1172 let s = "(([int16 0], [[int16 0]], [[[int16 0]]]), \
1173 (@an [], [@an []], [[@an []]]), \
1174 (@aan [], [@aan []]))";
1175 assert_eq!(
1176 Value::new((
1177 (Some(0_i16), Some(Some(0_i16)), Some(Some(Some(0_i16))),),
1178 (None::<i16>, Some(None::<i16>), Some(Some(None::<i16>)),),
1179 (None::<Option<i16>>, Some(None::<Option<i16>>)),
1180 ))
1181 .to_string(),
1182 s,
1183 );
1184
1185 #[cfg(unix)]
1186 assert_eq!(
1187 Value::new(vec![
1188 Fd::from(unsafe { BorrowedFd::borrow_raw(0) }),
1189 Fd::from(unsafe { BorrowedFd::borrow_raw(-100) })
1190 ])
1191 .to_string(),
1192 "[handle 0, -100]"
1193 );
1194
1195 #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1196 let s = "(@mb nothing, @mb nothing, \
1197 @ma{sv} {\"size\": <(800, 600)>}, \
1198 [<1>, <{\"dimension\": <([2.4, 1.], \
1199 @mmn 200, <(byte 0x03, \"Hello!\")>)>}>], \
1200 7777, objectpath \"/\", 8888)";
1201 #[cfg(feature = "option-as-array")]
1202 let s = "(@ab [], @ab [], [{\"size\": <(800, 600)>}], \
1203 [<1>, <{\"dimension\": <([2.4, 1.], [[int16 200]], \
1204 <(byte 0x03, \"Hello!\")>)>}>], 7777, objectpath \"/\", 8888)";
1205 assert_eq!(
1206 Value::new((
1207 None::<bool>,
1208 None::<bool>,
1209 Some(
1210 vec![("size", Value::new((800, 600)))]
1211 .into_iter()
1212 .collect::<HashMap<_, _>>()
1213 ),
1214 vec![
1215 Value::new(1),
1216 Value::new(
1217 vec![(
1218 "dimension",
1219 Value::new((
1220 vec![2.4, 1.],
1221 Some(Some(200_i16)),
1222 Value::new((3_u8, "Hello!"))
1223 ))
1224 )]
1225 .into_iter()
1226 .collect::<HashMap<_, _>>()
1227 )
1228 ],
1229 7777,
1230 ObjectPath::from_static_str("/").unwrap(),
1231 8888
1232 ))
1233 .to_string(),
1234 s,
1235 );
1236 }
1237 }
1238}