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 value_signature(&self) -> &Signature {
251 match self {
252 Value::U8(_) => u8::SIGNATURE,
253 Value::Bool(_) => bool::SIGNATURE,
254 Value::I16(_) => i16::SIGNATURE,
255 Value::U16(_) => u16::SIGNATURE,
256 Value::I32(_) => i32::SIGNATURE,
257 Value::U32(_) => u32::SIGNATURE,
258 Value::I64(_) => i64::SIGNATURE,
259 Value::U64(_) => u64::SIGNATURE,
260 Value::F64(_) => f64::SIGNATURE,
261 Value::Str(_) => <&str>::SIGNATURE,
262 Value::Signature(_) => Signature::SIGNATURE,
263 Value::ObjectPath(_) => ObjectPath::SIGNATURE,
264 Value::Value(_) => &Signature::Variant,
265
266 Value::Array(value) => value.signature(),
268 Value::Dict(value) => value.signature(),
269 Value::Structure(value) => value.signature(),
270 #[cfg(feature = "gvariant")]
271 Value::Maybe(value) => value.signature(),
272
273 #[cfg(unix)]
274 Value::Fd(_) => Fd::SIGNATURE,
275 }
276 }
277
278 pub fn try_clone(&self) -> crate::Result<Self> {
286 Ok(match self {
287 Value::U8(v) => Value::U8(*v),
288 Value::Bool(v) => Value::Bool(*v),
289 Value::I16(v) => Value::I16(*v),
290 Value::U16(v) => Value::U16(*v),
291 Value::I32(v) => Value::I32(*v),
292 Value::U32(v) => Value::U32(*v),
293 Value::I64(v) => Value::I64(*v),
294 Value::U64(v) => Value::U64(*v),
295 Value::F64(v) => Value::F64(*v),
296 Value::Str(v) => Value::Str(v.clone()),
297 Value::Signature(v) => Value::Signature(v.clone()),
298 Value::ObjectPath(v) => Value::ObjectPath(v.clone()),
299 Value::Value(v) => Value::Value(Box::new(v.try_clone()?)),
300 Value::Array(v) => Value::Array(v.try_clone()?),
301 Value::Dict(v) => Value::Dict(v.try_clone()?),
302 Value::Structure(v) => Value::Structure(v.try_clone()?),
303 #[cfg(feature = "gvariant")]
304 Value::Maybe(v) => Value::Maybe(v.try_clone()?),
305 #[cfg(unix)]
306 Value::Fd(v) => Value::Fd(v.try_clone()?),
307 })
308 }
309
310 pub(crate) fn serialize_value_as_struct_field<S>(
311 &self,
312 name: &'static str,
313 serializer: &mut S,
314 ) -> Result<(), S::Error>
315 where
316 S: SerializeStruct,
317 {
318 serialize_value!(self serializer.serialize_field name)
319 }
320
321 pub(crate) fn serialize_value_as_tuple_struct_field<S>(
322 &self,
323 serializer: &mut S,
324 ) -> Result<(), S::Error>
325 where
326 S: SerializeTupleStruct,
327 {
328 serialize_value!(self serializer.serialize_field)
329 }
330
331 pub(crate) fn serialize_value_as_seq_element<S>(
333 &self,
334 serializer: &mut S,
335 ) -> Result<(), S::Error>
336 where
337 S: SerializeSeq,
338 {
339 serialize_value!(self serializer.serialize_element)
340 }
341
342 pub(crate) fn serialize_value_as_dict_key<S>(&self, serializer: &mut S) -> Result<(), S::Error>
343 where
344 S: SerializeMap,
345 {
346 serialize_value!(self serializer.serialize_key)
347 }
348
349 pub(crate) fn serialize_value_as_dict_value<S>(
350 &self,
351 serializer: &mut S,
352 ) -> Result<(), S::Error>
353 where
354 S: SerializeMap,
355 {
356 serialize_value!(self serializer.serialize_value)
357 }
358
359 #[cfg(feature = "gvariant")]
360 pub(crate) fn serialize_value_as_some<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
361 where
362 S: Serializer,
363 {
364 serialize_value!(self serializer.serialize_some)
365 }
366
367 pub fn downcast<T>(self) -> Result<T, crate::Error>
409 where
410 T: TryFrom<Value<'a>>,
411 <T as TryFrom<Value<'a>>>::Error: Into<crate::Error>,
412 {
413 if let Value::Value(v) = self {
414 T::try_from(*v)
415 } else {
416 T::try_from(self)
417 }
418 .map_err(Into::into)
419 }
420
421 pub fn downcast_ref<T>(&'a self) -> Result<T, crate::Error>
459 where
460 T: TryFrom<&'a Value<'a>>,
461 <T as TryFrom<&'a Value<'a>>>::Error: Into<crate::Error>,
462 {
463 if let Value::Value(v) = self {
464 <T>::try_from(v)
465 } else {
466 <T>::try_from(self)
467 }
468 .map_err(Into::into)
469 }
470}
471
472impl Display for Value<'_> {
473 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
474 value_display_fmt(self, f, true)
475 }
476}
477
478pub(crate) fn value_display_fmt(
480 value: &Value<'_>,
481 f: &mut std::fmt::Formatter<'_>,
482 type_annotate: bool,
483) -> std::fmt::Result {
484 match value {
485 Value::U8(num) => {
486 if type_annotate {
487 f.write_str("byte ")?;
488 }
489 write!(f, "0x{num:02x}")
490 }
491 Value::Bool(boolean) => {
492 write!(f, "{boolean}")
493 }
494 Value::I16(num) => {
495 if type_annotate {
496 f.write_str("int16 ")?;
497 }
498 write!(f, "{num}")
499 }
500 Value::U16(num) => {
501 if type_annotate {
502 f.write_str("uint16 ")?;
503 }
504 write!(f, "{num}")
505 }
506 Value::I32(num) => {
507 write!(f, "{num}")
509 }
510 Value::U32(num) => {
511 if type_annotate {
512 f.write_str("uint32 ")?;
513 }
514 write!(f, "{num}")
515 }
516 Value::I64(num) => {
517 if type_annotate {
518 f.write_str("int64 ")?;
519 }
520 write!(f, "{num}")
521 }
522 Value::U64(num) => {
523 if type_annotate {
524 f.write_str("uint64 ")?;
525 }
526 write!(f, "{num}")
527 }
528 Value::F64(num) => {
529 if num.fract() == 0. {
530 write!(f, "{num}.")
532 } else {
533 write!(f, "{num}")
534 }
535 }
536 Value::Str(string) => {
537 write!(f, "{:?}", string.as_str())
538 }
539 Value::Signature(val) => {
540 if type_annotate {
541 f.write_str("signature ")?;
542 }
543 write!(f, "{:?}", val.to_string())
544 }
545 Value::ObjectPath(val) => {
546 if type_annotate {
547 f.write_str("objectpath ")?;
548 }
549 write!(f, "{:?}", val.as_str())
550 }
551 Value::Value(child) => {
552 f.write_char('<')?;
553
554 value_display_fmt(child, f, true)?;
557
558 f.write_char('>')?;
559 Ok(())
560 }
561 Value::Array(array) => array_display_fmt(array, f, type_annotate),
562 Value::Dict(dict) => dict_display_fmt(dict, f, type_annotate),
563 Value::Structure(structure) => structure_display_fmt(structure, f, type_annotate),
564 #[cfg(feature = "gvariant")]
565 Value::Maybe(maybe) => maybe_display_fmt(maybe, f, type_annotate),
566 #[cfg(unix)]
567 Value::Fd(handle) => {
568 if type_annotate {
569 f.write_str("handle ")?;
570 }
571 write!(f, "{handle}")
572 }
573 }
574}
575
576impl Serialize for Value<'_> {
577 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
578 where
579 S: Serializer,
580 {
581 let mut structure = serializer.serialize_struct("Variant", 2)?;
583
584 let signature = self.value_signature();
585 structure.serialize_field("signature", &signature)?;
586
587 self.serialize_value_as_struct_field("value", &mut structure)?;
588
589 structure.end()
590 }
591}
592
593impl<'de: 'a, 'a> Deserialize<'de> for Value<'a> {
594 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
595 where
596 D: Deserializer<'de>,
597 {
598 let visitor = ValueVisitor;
599
600 deserializer.deserialize_any(visitor)
601 }
602}
603
604struct ValueVisitor;
605
606impl<'de> Visitor<'de> for ValueVisitor {
607 type Value = Value<'de>;
608
609 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
610 formatter.write_str("a Value")
611 }
612
613 fn visit_seq<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
614 where
615 V: SeqAccess<'de>,
616 {
617 let signature = visitor.next_element::<Signature>()?.ok_or_else(|| {
618 Error::invalid_value(Unexpected::Other("nothing"), &"a Value signature")
619 })?;
620 let seed = ValueSeed::<Value<'_>> {
621 signature: &signature,
622 phantom: PhantomData,
623 };
624
625 visitor
626 .next_element_seed(seed)?
627 .ok_or_else(|| Error::invalid_value(Unexpected::Other("nothing"), &"a Value value"))
628 }
629
630 fn visit_map<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
631 where
632 V: MapAccess<'de>,
633 {
634 let (_, signature) = visitor.next_entry::<&str, Signature>()?.ok_or_else(|| {
635 Error::invalid_value(Unexpected::Other("nothing"), &"a Value signature")
636 })?;
637 let _ = visitor.next_key::<&str>()?;
638
639 let seed = ValueSeed::<Value<'_>> {
640 signature: &signature,
641 phantom: PhantomData,
642 };
643 visitor.next_value_seed(seed)
644 }
645}
646
647pub(crate) struct SignatureSeed<'sig> {
648 pub signature: &'sig Signature,
649}
650
651impl SignatureSeed<'_> {
652 pub(crate) fn visit_array<'de, V>(self, mut visitor: V) -> Result<Array<'de>, V::Error>
653 where
654 V: SeqAccess<'de>,
655 {
656 let element_signature = match self.signature {
657 Signature::Array(child) => child.signature(),
658 _ => {
659 return Err(Error::invalid_type(
660 Unexpected::Str(&self.signature.to_string()),
661 &"an array signature",
662 ))
663 }
664 };
665 let mut array = Array::new_full_signature(self.signature);
666
667 while let Some(elem) = visitor.next_element_seed(ValueSeed::<Value<'_>> {
668 signature: element_signature,
669 phantom: PhantomData,
670 })? {
671 elem.value_signature();
672 array.append(elem).map_err(Error::custom)?;
673 }
674
675 Ok(array)
676 }
677
678 pub(crate) fn visit_struct<'de, V>(self, mut visitor: V) -> Result<Structure<'de>, V::Error>
679 where
680 V: SeqAccess<'de>,
681 {
682 let fields_signatures = match self.signature {
683 Signature::Structure(fields) => fields.iter(),
684 _ => {
685 return Err(Error::invalid_type(
686 Unexpected::Str(&self.signature.to_string()),
687 &"a structure signature",
688 ))
689 }
690 };
691
692 let mut builder = StructureBuilder::new();
693 for field_signature in fields_signatures {
694 if let Some(field) = visitor.next_element_seed(ValueSeed::<Value<'_>> {
695 signature: field_signature,
696 phantom: PhantomData,
697 })? {
698 builder = builder.append_field(field);
699 }
700 }
701 Ok(builder.build_with_signature(self.signature))
702 }
703}
704
705impl<'sig, T> From<ValueSeed<'sig, T>> for SignatureSeed<'sig> {
706 fn from(seed: ValueSeed<'sig, T>) -> Self {
707 SignatureSeed {
708 signature: seed.signature,
709 }
710 }
711}
712
713struct ValueSeed<'sig, T> {
714 signature: &'sig Signature,
715 phantom: PhantomData<T>,
716}
717
718impl<'de, T> ValueSeed<'_, T>
719where
720 T: Deserialize<'de>,
721{
722 #[inline]
723 fn visit_array<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
724 where
725 V: SeqAccess<'de>,
726 {
727 SignatureSeed::from(self)
728 .visit_array(visitor)
729 .map(Value::Array)
730 }
731
732 #[inline]
733 fn visit_struct<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
734 where
735 V: SeqAccess<'de>,
736 {
737 SignatureSeed::from(self)
738 .visit_struct(visitor)
739 .map(Value::Structure)
740 }
741
742 #[inline]
743 fn visit_variant_as_seq<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
744 where
745 V: SeqAccess<'de>,
746 {
747 ValueVisitor
748 .visit_seq(visitor)
749 .map(|v| Value::Value(Box::new(v)))
750 }
751
752 #[inline]
753 fn visit_variant_as_map<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
754 where
755 V: MapAccess<'de>,
756 {
757 ValueVisitor
758 .visit_map(visitor)
759 .map(|v| Value::Value(Box::new(v)))
760 }
761}
762
763macro_rules! value_seed_basic_method {
764 ($name:ident, $type:ty) => {
765 #[inline]
766 fn $name<E>(self, value: $type) -> Result<Value<'static>, E>
767 where
768 E: serde::de::Error,
769 {
770 Ok(value.into())
771 }
772 };
773}
774
775impl<'de, T> Visitor<'de> for ValueSeed<'_, T>
776where
777 T: Deserialize<'de>,
778{
779 type Value = Value<'de>;
780
781 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
782 formatter.write_str("a Value value")
783 }
784
785 value_seed_basic_method!(visit_bool, bool);
786 value_seed_basic_method!(visit_i16, i16);
787 value_seed_basic_method!(visit_i64, i64);
788 value_seed_basic_method!(visit_u8, u8);
789 value_seed_basic_method!(visit_u16, u16);
790 value_seed_basic_method!(visit_u32, u32);
791 value_seed_basic_method!(visit_u64, u64);
792 value_seed_basic_method!(visit_f64, f64);
793
794 fn visit_i32<E>(self, value: i32) -> Result<Value<'de>, E>
795 where
796 E: serde::de::Error,
797 {
798 let v = match &self.signature {
799 #[cfg(unix)]
800 Signature::Fd => {
801 let fd = unsafe { std::os::fd::BorrowedFd::borrow_raw(value) };
803 Fd::Borrowed(fd).into()
804 }
805 _ => value.into(),
806 };
807
808 Ok(v)
809 }
810
811 #[inline]
812 fn visit_str<E>(self, value: &str) -> Result<Value<'de>, E>
813 where
814 E: serde::de::Error,
815 {
816 self.visit_string(String::from(value))
817 }
818
819 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
820 where
821 E: Error,
822 {
823 match &self.signature {
824 Signature::Str => Ok(Value::Str(Str::from(v))),
825 Signature::Signature => Signature::try_from(v)
826 .map(Value::Signature)
827 .map_err(Error::custom),
828 Signature::ObjectPath => Ok(Value::ObjectPath(ObjectPath::from_str_unchecked(v))),
829 _ => {
830 let expected = format!(
831 "`{}`, `{}` or `{}`",
832 <&str>::SIGNATURE_STR,
833 Signature::SIGNATURE_STR,
834 ObjectPath::SIGNATURE_STR,
835 );
836 Err(Error::invalid_type(
837 Unexpected::Str(&self.signature.to_string()),
838 &expected.as_str(),
839 ))
840 }
841 }
842 }
843
844 fn visit_seq<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
845 where
846 V: SeqAccess<'de>,
847 {
848 match &self.signature {
849 Signature::Array(_) => self.visit_array(visitor),
851 Signature::Structure(_) => self.visit_struct(visitor),
852 Signature::Variant => self.visit_variant_as_seq(visitor),
853 s => Err(Error::invalid_value(
854 Unexpected::Str(&s.to_string()),
855 &"a Value signature",
856 )),
857 }
858 }
859
860 fn visit_map<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
861 where
862 V: MapAccess<'de>,
863 {
864 let (key_signature, value_signature) = match &self.signature {
865 Signature::Dict { key, value } => (key.signature().clone(), value.signature().clone()),
866 Signature::Variant => return self.visit_variant_as_map(visitor),
867 _ => {
868 return Err(Error::invalid_type(
869 Unexpected::Str(&self.signature.to_string()),
870 &"a dict signature",
871 ))
872 }
873 };
874
875 let mut dict = Dict::new_full_signature(self.signature);
876
877 while let Some((key, value)) = visitor.next_entry_seed(
878 ValueSeed::<Value<'_>> {
879 signature: &key_signature,
880 phantom: PhantomData,
881 },
882 ValueSeed::<Value<'_>> {
883 signature: &value_signature,
884 phantom: PhantomData,
885 },
886 )? {
887 dict.append(key, value).map_err(Error::custom)?;
888 }
889
890 Ok(Value::Dict(dict))
891 }
892
893 #[cfg(feature = "gvariant")]
894 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
895 where
896 D: Deserializer<'de>,
897 {
898 let child_signature = match &self.signature {
899 Signature::Maybe(child) => child.signature().clone(),
900 _ => {
901 return Err(Error::invalid_type(
902 Unexpected::Str(&self.signature.to_string()),
903 &"a maybe signature",
904 ))
905 }
906 };
907 let visitor = ValueSeed::<T> {
908 signature: &child_signature,
909 phantom: PhantomData,
910 };
911
912 deserializer
913 .deserialize_any(visitor)
914 .map(|v| Value::Maybe(Maybe::just_full_signature(v, self.signature)))
915 }
916
917 #[cfg(not(feature = "gvariant"))]
918 fn visit_some<D>(self, _deserializer: D) -> Result<Self::Value, D::Error>
919 where
920 D: Deserializer<'de>,
921 {
922 panic!("`Maybe` type is only supported for GVariant format but it's disabled");
923 }
924
925 #[cfg(feature = "gvariant")]
926 fn visit_none<E>(self) -> Result<Self::Value, E>
927 where
928 E: Error,
929 {
930 let value = Maybe::nothing_full_signature(self.signature);
931
932 Ok(Value::Maybe(value))
933 }
934
935 #[cfg(not(feature = "gvariant"))]
936 fn visit_none<E>(self) -> Result<Self::Value, E>
937 where
938 E: Error,
939 {
940 panic!("`Maybe` type is only supported for GVariant format but it's disabled");
941 }
942}
943
944impl<'de, T> DeserializeSeed<'de> for ValueSeed<'_, T>
945where
946 T: Deserialize<'de>,
947{
948 type Value = Value<'de>;
949
950 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
951 where
952 D: Deserializer<'de>,
953 {
954 deserializer.deserialize_any(self)
955 }
956}
957
958impl Type for Value<'_> {
959 const SIGNATURE: &'static Signature = &Signature::Variant;
960}
961
962impl<'a> TryFrom<&Value<'a>> for Value<'a> {
963 type Error = crate::Error;
964
965 fn try_from(value: &Value<'a>) -> crate::Result<Value<'a>> {
966 value.try_clone()
967 }
968}
969
970impl Clone for Value<'_> {
971 fn clone(&self) -> Self {
979 self.try_clone()
980 .expect("Process exceeded limit on maximum number of open file descriptors")
981 }
982}
983
984#[cfg(test)]
985mod tests {
986 use std::collections::HashMap;
987
988 use super::*;
989
990 #[test]
991 fn value_display() {
992 assert_eq!(
993 Value::new((
994 255_u8,
995 true,
996 -1_i16,
997 65535_u16,
998 -1,
999 1_u32,
1000 -9223372036854775808_i64,
1001 18446744073709551615_u64,
1002 (-1., 1.0, 11000000000., 1.1e-10)
1003 ))
1004 .to_string(),
1005 "(byte 0xff, true, int16 -1, uint16 65535, -1, uint32 1, \
1006 int64 -9223372036854775808, uint64 18446744073709551615, \
1007 (-1., 1., 11000000000., 0.00000000011))"
1008 );
1009
1010 assert_eq!(
1011 Value::new(vec![
1012 "", " ", "a", r#"""#, "'", "a'b", "a'\"b", "\\", "\n'\"",
1013 ])
1014 .to_string(),
1015 r#"["", " ", "a", "\"", "'", "a'b", "a'\"b", "\\", "\n'\""]"#
1016 );
1017 assert_eq!(
1018 Value::new(vec![
1019 "\x07\x08\x09\x0A\x0B\x0C\x0D",
1020 "\x7F",
1021 char::from_u32(0xD8000).unwrap().to_string().as_str()
1022 ])
1023 .to_string(),
1024 r#"["\u{7}\u{8}\t\n\u{b}\u{c}\r", "\u{7f}", "\u{d8000}"]"#
1025 );
1026
1027 assert_eq!(
1028 Value::new((
1029 vec![
1030 Signature::try_from("").unwrap(),
1031 Signature::try_from("(ysa{sd})").unwrap(),
1032 ],
1033 vec![
1034 ObjectPath::from_static_str("/").unwrap(),
1035 ObjectPath::from_static_str("/a/very/looooooooooooooooooooooooo0000o0ng/path")
1036 .unwrap(),
1037 ],
1038 vec![
1039 Value::new(0_u8),
1040 Value::new((Value::new(51), Value::new(Value::new(1_u32)))),
1041 ]
1042 ))
1043 .to_string(),
1044 "([signature \"\", \"(ysa{sd})\"], \
1045 [objectpath \"/\", \"/a/very/looooooooooooooooooooooooo0000o0ng/path\"], \
1046 [<byte 0x00>, <(<51>, <<uint32 1>>)>])"
1047 );
1048
1049 assert_eq!(Value::new(vec![] as Vec<Vec<i64>>).to_string(), "@aax []");
1050 assert_eq!(
1051 Value::new(vec![
1052 vec![0_i16, 1_i16],
1053 vec![2_i16, 3_i16],
1054 vec![4_i16, 5_i16]
1055 ])
1056 .to_string(),
1057 "[[int16 0, 1], [2, 3], [4, 5]]"
1058 );
1059 assert_eq!(
1060 Value::new(vec![
1061 b"Hello".to_vec(),
1062 b"Hell\0o".to_vec(),
1063 b"H\0ello\0".to_vec(),
1064 b"Hello\0".to_vec(),
1065 b"\0".to_vec(),
1066 b" \0".to_vec(),
1067 b"'\0".to_vec(),
1068 b"\n'\"\0".to_vec(),
1069 b"\\\0".to_vec(),
1070 ])
1071 .to_string(),
1072 "[[byte 0x48, 0x65, 0x6c, 0x6c, 0x6f], \
1073 [0x48, 0x65, 0x6c, 0x6c, 0x00, 0x6f], \
1074 [0x48, 0x00, 0x65, 0x6c, 0x6c, 0x6f, 0x00], \
1075 b\"Hello\", b\"\", b\" \", b\"'\", b\"\\n'\\\"\", b\"\\\\\"]"
1076 );
1077
1078 assert_eq!(
1079 Value::new(HashMap::<bool, bool>::new()).to_string(),
1080 "@a{bb} {}"
1081 );
1082 assert_eq!(
1083 Value::new(vec![(true, 0_i64)].into_iter().collect::<HashMap<_, _>>()).to_string(),
1084 "{true: int64 0}",
1085 );
1086 let val = Value::new(
1088 vec![(32_u16, 64_i64), (100_u16, 200_i64)]
1089 .into_iter()
1090 .collect::<HashMap<_, _>>(),
1091 )
1092 .to_string();
1093 assert!(val.starts_with('{'));
1094 assert!(val.ends_with('}'));
1095 assert_eq!(val.matches("uint16").count(), 1);
1096 assert_eq!(val.matches("int64").count(), 1);
1097
1098 let items_str = val.split(", ").collect::<Vec<_>>();
1099 assert_eq!(items_str.len(), 2);
1100 assert!(items_str
1101 .iter()
1102 .any(|str| str.contains("32") && str.contains(": ") && str.contains("64")));
1103 assert!(items_str
1104 .iter()
1105 .any(|str| str.contains("100") && str.contains(": ") && str.contains("200")));
1106
1107 assert_eq!(
1108 Value::new(((true,), (true, false), (true, true, false))).to_string(),
1109 "((true,), (true, false), (true, true, false))"
1110 );
1111
1112 #[cfg(any(feature = "gvariant", feature = "option-as-array"))]
1113 {
1114 #[cfg(unix)]
1115 use std::os::fd::BorrowedFd;
1116
1117 #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1118 let s = "((@mn 0, @mmn 0, @mmmn 0), \
1119 (@mn nothing, @mmn just nothing, @mmmn just just nothing), \
1120 (@mmn nothing, @mmmn just nothing))";
1121 #[cfg(feature = "option-as-array")]
1122 let s = "(([int16 0], [[int16 0]], [[[int16 0]]]), \
1123 (@an [], [@an []], [[@an []]]), \
1124 (@aan [], [@aan []]))";
1125 assert_eq!(
1126 Value::new((
1127 (Some(0_i16), Some(Some(0_i16)), Some(Some(Some(0_i16))),),
1128 (None::<i16>, Some(None::<i16>), Some(Some(None::<i16>)),),
1129 (None::<Option<i16>>, Some(None::<Option<i16>>)),
1130 ))
1131 .to_string(),
1132 s,
1133 );
1134
1135 #[cfg(unix)]
1136 assert_eq!(
1137 Value::new(vec![
1138 Fd::from(unsafe { BorrowedFd::borrow_raw(0) }),
1139 Fd::from(unsafe { BorrowedFd::borrow_raw(-100) })
1140 ])
1141 .to_string(),
1142 "[handle 0, -100]"
1143 );
1144
1145 #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1146 let s = "(@mb nothing, @mb nothing, \
1147 @ma{sv} {\"size\": <(800, 600)>}, \
1148 [<1>, <{\"dimension\": <([2.4, 1.], \
1149 @mmn 200, <(byte 0x03, \"Hello!\")>)>}>], \
1150 7777, objectpath \"/\", 8888)";
1151 #[cfg(feature = "option-as-array")]
1152 let s = "(@ab [], @ab [], [{\"size\": <(800, 600)>}], \
1153 [<1>, <{\"dimension\": <([2.4, 1.], [[int16 200]], \
1154 <(byte 0x03, \"Hello!\")>)>}>], 7777, objectpath \"/\", 8888)";
1155 assert_eq!(
1156 Value::new((
1157 None::<bool>,
1158 None::<bool>,
1159 Some(
1160 vec![("size", Value::new((800, 600)))]
1161 .into_iter()
1162 .collect::<HashMap<_, _>>()
1163 ),
1164 vec![
1165 Value::new(1),
1166 Value::new(
1167 vec![(
1168 "dimension",
1169 Value::new((
1170 vec![2.4, 1.],
1171 Some(Some(200_i16)),
1172 Value::new((3_u8, "Hello!"))
1173 ))
1174 )]
1175 .into_iter()
1176 .collect::<HashMap<_, _>>()
1177 )
1178 ],
1179 7777,
1180 ObjectPath::from_static_str("/").unwrap(),
1181 8888
1182 ))
1183 .to_string(),
1184 s,
1185 );
1186 }
1187 }
1188}