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