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};
19use static_assertions::assert_impl_all;
20
21use crate::{
22 array_display_fmt, dict_display_fmt, signature_parser::SignatureParser, structure_display_fmt,
23 utils::*, Array, Basic, Dict, DynamicType, ObjectPath, OwnedValue, Signature, Str, Structure,
24 StructureBuilder, Type,
25};
26#[cfg(feature = "gvariant")]
27use crate::{maybe_display_fmt, Maybe};
28
29#[cfg(unix)]
30use crate::Fd;
31
32#[derive(Debug, PartialEq, PartialOrd)]
81pub enum Value<'a> {
82 U8(u8),
84 Bool(bool),
85 I16(i16),
86 U16(u16),
87 I32(i32),
88 U32(u32),
89 I64(i64),
90 U64(u64),
91 F64(f64),
92 Str(Str<'a>),
93 Signature(Signature<'a>),
94 ObjectPath(ObjectPath<'a>),
95 Value(Box<Value<'a>>),
96
97 Array(Array<'a>),
99 Dict(Dict<'a, 'a>),
100 Structure(Structure<'a>),
101 #[cfg(feature = "gvariant")]
102 Maybe(Maybe<'a>),
103
104 #[cfg(unix)]
105 Fd(Fd<'a>),
106}
107
108impl Hash for Value<'_> {
109 fn hash<H: Hasher>(&self, state: &mut H) {
110 discriminant(self).hash(state);
111 match self {
112 Self::U8(inner) => inner.hash(state),
113 Self::Bool(inner) => inner.hash(state),
114 Self::I16(inner) => inner.hash(state),
115 Self::U16(inner) => inner.hash(state),
116 Self::I32(inner) => inner.hash(state),
117 Self::U32(inner) => inner.hash(state),
118 Self::I64(inner) => inner.hash(state),
119 Self::U64(inner) => inner.hash(state),
120 Self::F64(inner) if *inner == 0. => 0f64.to_le_bytes().hash(state),
123 Self::F64(inner) => inner.to_le_bytes().hash(state),
124 Self::Str(inner) => inner.hash(state),
125 Self::Signature(inner) => inner.hash(state),
126 Self::ObjectPath(inner) => inner.hash(state),
127 Self::Value(inner) => inner.hash(state),
128 Self::Array(inner) => inner.hash(state),
129 Self::Dict(inner) => inner.hash(state),
130 Self::Structure(inner) => inner.hash(state),
131 #[cfg(feature = "gvariant")]
132 Self::Maybe(inner) => inner.hash(state),
133 #[cfg(unix)]
134 Self::Fd(inner) => inner.hash(state),
135 }
136 }
137}
138
139impl Eq for Value<'_> {}
140
141impl Ord for Value<'_> {
142 fn cmp(&self, other: &Self) -> Ordering {
143 self.partial_cmp(other)
144 .unwrap_or_else(|| match (self, other) {
145 (Self::F64(lhs), Self::F64(rhs)) => lhs.total_cmp(rhs),
146 _ => unreachable!(),
151 })
152 }
153}
154
155assert_impl_all!(Value<'_>: Send, Sync, Unpin);
156
157macro_rules! serialize_value {
158 ($self:ident $serializer:ident.$method:ident $($first_arg:expr)*) => {
159 match $self {
160 Value::U8(value) => $serializer.$method($($first_arg,)* value),
161 Value::Bool(value) => $serializer.$method($($first_arg,)* value),
162 Value::I16(value) => $serializer.$method($($first_arg,)* value),
163 Value::U16(value) => $serializer.$method($($first_arg,)* value),
164 Value::I32(value) => $serializer.$method($($first_arg,)* value),
165 Value::U32(value) => $serializer.$method($($first_arg,)* value),
166 Value::I64(value) => $serializer.$method($($first_arg,)* value),
167 Value::U64(value) => $serializer.$method($($first_arg,)* value),
168 Value::F64(value) => $serializer.$method($($first_arg,)* value),
169 Value::Str(value) => $serializer.$method($($first_arg,)* value),
170 Value::Signature(value) => $serializer.$method($($first_arg,)* value),
171 Value::ObjectPath(value) => $serializer.$method($($first_arg,)* value),
172 Value::Value(value) => $serializer.$method($($first_arg,)* value),
173
174 Value::Array(value) => $serializer.$method($($first_arg,)* value),
176 Value::Dict(value) => $serializer.$method($($first_arg,)* value),
177 Value::Structure(value) => $serializer.$method($($first_arg,)* value),
178 #[cfg(feature = "gvariant")]
179 Value::Maybe(value) => $serializer.$method($($first_arg,)* value),
180
181 #[cfg(unix)]
182 Value::Fd(value) => $serializer.$method($($first_arg,)* value),
183 }
184 }
185}
186
187impl<'a> Value<'a> {
188 pub fn new<T>(value: T) -> Self
207 where
208 T: Into<Self> + DynamicType,
209 {
210 if value.dynamic_signature() == VARIANT_SIGNATURE_STR {
212 Self::Value(Box::new(value.into()))
213 } else {
214 value.into()
215 }
216 }
217
218 pub fn try_to_owned(&self) -> crate::Result<OwnedValue> {
225 Ok(OwnedValue(match self {
226 Value::U8(v) => Value::U8(*v),
227 Value::Bool(v) => Value::Bool(*v),
228 Value::I16(v) => Value::I16(*v),
229 Value::U16(v) => Value::U16(*v),
230 Value::I32(v) => Value::I32(*v),
231 Value::U32(v) => Value::U32(*v),
232 Value::I64(v) => Value::I64(*v),
233 Value::U64(v) => Value::U64(*v),
234 Value::F64(v) => Value::F64(*v),
235 Value::Str(v) => Value::Str(v.to_owned()),
236 Value::Signature(v) => Value::Signature(v.to_owned()),
237 Value::ObjectPath(v) => Value::ObjectPath(v.to_owned()),
238 Value::Value(v) => {
239 let o = OwnedValue::try_from(&**v)?;
240 Value::Value(Box::new(o.into_inner()))
241 }
242
243 Value::Array(v) => Value::Array(v.try_to_owned()?),
244 Value::Dict(v) => Value::Dict(v.try_to_owned()?),
245 Value::Structure(v) => Value::Structure(v.try_to_owned()?),
246 #[cfg(feature = "gvariant")]
247 Value::Maybe(v) => Value::Maybe(v.try_to_owned()?),
248 #[cfg(unix)]
249 Value::Fd(v) => Value::Fd(v.try_to_owned()?),
250 }))
251 }
252
253 pub fn value_signature(&self) -> Signature<'_> {
255 match self {
256 Value::U8(_) => u8::signature(),
257 Value::Bool(_) => bool::signature(),
258 Value::I16(_) => i16::signature(),
259 Value::U16(_) => u16::signature(),
260 Value::I32(_) => i32::signature(),
261 Value::U32(_) => u32::signature(),
262 Value::I64(_) => i64::signature(),
263 Value::U64(_) => u64::signature(),
264 Value::F64(_) => f64::signature(),
265 Value::Str(_) => <&str>::signature(),
266 Value::Signature(_) => Signature::signature(),
267 Value::ObjectPath(_) => ObjectPath::signature(),
268 Value::Value(_) => Signature::from_static_str_unchecked("v"),
269
270 Value::Array(value) => value.full_signature().as_ref(),
272 Value::Dict(value) => value.full_signature().as_ref(),
273 Value::Structure(value) => value.full_signature().as_ref(),
274 #[cfg(feature = "gvariant")]
275 Value::Maybe(value) => value.full_signature().as_ref(),
276
277 #[cfg(unix)]
278 Value::Fd(_) => Fd::signature(),
279 }
280 }
281
282 pub fn try_clone(&self) -> crate::Result<Self> {
290 Ok(match self {
291 Value::U8(v) => Value::U8(*v),
292 Value::Bool(v) => Value::Bool(*v),
293 Value::I16(v) => Value::I16(*v),
294 Value::U16(v) => Value::U16(*v),
295 Value::I32(v) => Value::I32(*v),
296 Value::U32(v) => Value::U32(*v),
297 Value::I64(v) => Value::I64(*v),
298 Value::U64(v) => Value::U64(*v),
299 Value::F64(v) => Value::F64(*v),
300 Value::Str(v) => Value::Str(v.clone()),
301 Value::Signature(v) => Value::Signature(v.clone()),
302 Value::ObjectPath(v) => Value::ObjectPath(v.clone()),
303 Value::Value(v) => Value::Value(Box::new(v.try_clone()?)),
304 Value::Array(v) => Value::Array(v.try_clone()?),
305 Value::Dict(v) => Value::Dict(v.try_clone()?),
306 Value::Structure(v) => Value::Structure(v.try_clone()?),
307 #[cfg(feature = "gvariant")]
308 Value::Maybe(v) => Value::Maybe(v.try_clone()?),
309 #[cfg(unix)]
310 Value::Fd(v) => Value::Fd(v.try_clone()?),
311 })
312 }
313
314 pub(crate) fn serialize_value_as_struct_field<S>(
315 &self,
316 name: &'static str,
317 serializer: &mut S,
318 ) -> Result<(), S::Error>
319 where
320 S: SerializeStruct,
321 {
322 serialize_value!(self serializer.serialize_field name)
323 }
324
325 pub(crate) fn serialize_value_as_tuple_struct_field<S>(
326 &self,
327 serializer: &mut S,
328 ) -> Result<(), S::Error>
329 where
330 S: SerializeTupleStruct,
331 {
332 serialize_value!(self serializer.serialize_field)
333 }
334
335 pub(crate) fn serialize_value_as_seq_element<S>(
337 &self,
338 serializer: &mut S,
339 ) -> Result<(), S::Error>
340 where
341 S: SerializeSeq,
342 {
343 serialize_value!(self serializer.serialize_element)
344 }
345
346 pub(crate) fn serialize_value_as_dict_key<S>(&self, serializer: &mut S) -> Result<(), S::Error>
347 where
348 S: SerializeMap,
349 {
350 serialize_value!(self serializer.serialize_key)
351 }
352
353 pub(crate) fn serialize_value_as_dict_value<S>(
354 &self,
355 serializer: &mut S,
356 ) -> Result<(), S::Error>
357 where
358 S: SerializeMap,
359 {
360 serialize_value!(self serializer.serialize_value)
361 }
362
363 #[cfg(feature = "gvariant")]
364 pub(crate) fn serialize_value_as_some<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
365 where
366 S: Serializer,
367 {
368 serialize_value!(self serializer.serialize_some)
369 }
370
371 pub fn downcast<T>(self) -> Result<T, crate::Error>
413 where
414 T: ?Sized + TryFrom<Value<'a>>,
415 <T as TryFrom<Value<'a>>>::Error: Into<crate::Error>,
416 {
417 if let Value::Value(v) = self {
418 T::try_from(*v)
419 } else {
420 T::try_from(self)
421 }
422 .map_err(Into::into)
423 }
424
425 pub fn downcast_ref<T>(&'a self) -> Result<T, crate::Error>
463 where
464 T: ?Sized + TryFrom<&'a Value<'a>>,
465 <T as TryFrom<&'a Value<'a>>>::Error: Into<crate::Error>,
466 {
467 if let Value::Value(v) = self {
468 <T>::try_from(v)
469 } else {
470 <T>::try_from(self)
471 }
472 .map_err(Into::into)
473 }
474}
475
476impl Display for Value<'_> {
477 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
478 value_display_fmt(self, f, true)
479 }
480}
481
482pub(crate) fn value_display_fmt(
484 value: &Value<'_>,
485 f: &mut std::fmt::Formatter<'_>,
486 type_annotate: bool,
487) -> std::fmt::Result {
488 match value {
489 Value::U8(num) => {
490 if type_annotate {
491 f.write_str("byte ")?;
492 }
493 write!(f, "0x{:02x}", num)
494 }
495 Value::Bool(boolean) => {
496 write!(f, "{}", boolean)
497 }
498 Value::I16(num) => {
499 if type_annotate {
500 f.write_str("int16 ")?;
501 }
502 write!(f, "{}", num)
503 }
504 Value::U16(num) => {
505 if type_annotate {
506 f.write_str("uint16 ")?;
507 }
508 write!(f, "{}", num)
509 }
510 Value::I32(num) => {
511 write!(f, "{}", num)
513 }
514 Value::U32(num) => {
515 if type_annotate {
516 f.write_str("uint32 ")?;
517 }
518 write!(f, "{}", num)
519 }
520 Value::I64(num) => {
521 if type_annotate {
522 f.write_str("int64 ")?;
523 }
524 write!(f, "{}", num)
525 }
526 Value::U64(num) => {
527 if type_annotate {
528 f.write_str("uint64 ")?;
529 }
530 write!(f, "{}", num)
531 }
532 Value::F64(num) => {
533 if num.fract() == 0. {
534 write!(f, "{}.", num)
536 } else {
537 write!(f, "{}", num)
538 }
539 }
540 Value::Str(string) => {
541 write!(f, "{:?}", string.as_str())
542 }
543 Value::Signature(val) => {
544 if type_annotate {
545 f.write_str("signature ")?;
546 }
547 write!(f, "{:?}", val.as_str())
548 }
549 Value::ObjectPath(val) => {
550 if type_annotate {
551 f.write_str("objectpath ")?;
552 }
553 write!(f, "{:?}", val.as_str())
554 }
555 Value::Value(child) => {
556 f.write_char('<')?;
557
558 value_display_fmt(child, f, true)?;
561
562 f.write_char('>')?;
563 Ok(())
564 }
565 Value::Array(array) => array_display_fmt(array, f, type_annotate),
566 Value::Dict(dict) => dict_display_fmt(dict, f, type_annotate),
567 Value::Structure(structure) => structure_display_fmt(structure, f, type_annotate),
568 #[cfg(feature = "gvariant")]
569 Value::Maybe(maybe) => maybe_display_fmt(maybe, f, type_annotate),
570 #[cfg(unix)]
571 Value::Fd(handle) => {
572 if type_annotate {
573 f.write_str("handle ")?;
574 }
575 write!(f, "{}", handle)
576 }
577 }
578}
579
580impl<'a> Serialize for Value<'a> {
581 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
582 where
583 S: Serializer,
584 {
585 let mut structure = serializer.serialize_struct("zvariant::Value", 2)?;
587
588 let signature = self.value_signature();
589 structure.serialize_field("zvariant::Value::Signature", &signature)?;
590
591 self.serialize_value_as_struct_field("zvariant::Value::Value", &mut structure)?;
592
593 structure.end()
594 }
595}
596
597impl<'de: 'a, 'a> Deserialize<'de> for Value<'a> {
598 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
599 where
600 D: Deserializer<'de>,
601 {
602 let visitor = ValueVisitor;
603
604 deserializer.deserialize_any(visitor)
605 }
606}
607
608struct ValueVisitor;
613
614impl<'de> Visitor<'de> for ValueVisitor {
615 type Value = Value<'de>;
616
617 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
618 formatter.write_str("a Value")
619 }
620
621 fn visit_seq<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
622 where
623 V: SeqAccess<'de>,
624 {
625 let signature = visitor.next_element::<Signature<'_>>()?.ok_or_else(|| {
626 Error::invalid_value(Unexpected::Other("nothing"), &"a Value signature")
627 })?;
628 let seed = ValueSeed::<Value<'_>> {
629 signature,
630 phantom: PhantomData,
631 };
632
633 visitor
634 .next_element_seed(seed)?
635 .ok_or_else(|| Error::invalid_value(Unexpected::Other("nothing"), &"a Value value"))
636 }
637
638 fn visit_map<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
639 where
640 V: MapAccess<'de>,
641 {
642 let (_, signature) = visitor
643 .next_entry::<&str, Signature<'_>>()?
644 .ok_or_else(|| {
645 Error::invalid_value(Unexpected::Other("nothing"), &"a Value signature")
646 })?;
647 let _ = visitor.next_key::<&str>()?;
648
649 let seed = ValueSeed::<Value<'_>> {
650 signature,
651 phantom: PhantomData,
652 };
653 visitor.next_value_seed(seed)
654 }
655}
656
657pub(crate) struct SignatureSeed<'de> {
658 pub signature: Signature<'de>,
659}
660
661impl<'de> SignatureSeed<'de> {
662 pub(crate) fn visit_array<V>(self, mut visitor: V) -> Result<Array<'de>, V::Error>
663 where
664 V: SeqAccess<'de>,
665 {
666 let element_signature = self.signature.slice(1..);
667 let mut array = Array::new_full_signature(self.signature.clone());
668
669 while let Some(elem) = visitor.next_element_seed(ValueSeed::<Value<'_>> {
670 signature: element_signature.clone(),
671 phantom: PhantomData,
672 })? {
673 elem.value_signature();
674 array.append(elem).map_err(Error::custom)?;
675 }
676
677 Ok(array)
678 }
679
680 pub(crate) fn visit_struct<V>(self, mut visitor: V) -> Result<Structure<'de>, V::Error>
681 where
682 V: SeqAccess<'de>,
683 {
684 let mut i = 1;
685 let signature_end = self.signature.len() - 1;
686 let mut builder = StructureBuilder::new();
687 while i < signature_end {
688 let fields_signature = self.signature.slice(i..signature_end);
689 let parser = SignatureParser::new(fields_signature.as_ref());
690 let len = parser.next_signature().map_err(Error::custom)?.len();
691 let field_signature = fields_signature.slice(0..len);
692 i += field_signature.len();
693
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<'de, T> From<ValueSeed<'de, T>> for SignatureSeed<'de> {
706 fn from(seed: ValueSeed<'de, T>) -> Self {
707 SignatureSeed {
708 signature: seed.signature,
709 }
710 }
711}
712
713struct ValueSeed<'de, T> {
714 signature: Signature<'de>,
715 phantom: PhantomData<T>,
716}
717
718impl<'de, T> ValueSeed<'de, 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<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
753macro_rules! value_seed_basic_method {
754 ($name:ident, $type:ty) => {
755 #[inline]
756 fn $name<E>(self, value: $type) -> Result<Value<'de>, E>
757 where
758 E: serde::de::Error,
759 {
760 Ok(value.into())
761 }
762 };
763}
764
765macro_rules! value_seed_str_method {
766 ($name:ident, $type:ty, $constructor:ident) => {
767 fn $name<E>(self, value: $type) -> Result<Value<'de>, E>
768 where
769 E: serde::de::Error,
770 {
771 match self.signature.as_str() {
772 <&str>::SIGNATURE_STR => Ok(Value::Str(Str::from(value))),
773 Signature::SIGNATURE_STR => Ok(Value::Signature(Signature::$constructor(value))),
774 ObjectPath::SIGNATURE_STR => Ok(Value::ObjectPath(ObjectPath::$constructor(value))),
775 _ => {
776 let expected = format!(
777 "`{}`, `{}` or `{}`",
778 <&str>::SIGNATURE_STR,
779 Signature::SIGNATURE_STR,
780 ObjectPath::SIGNATURE_STR,
781 );
782 Err(Error::invalid_type(
783 Unexpected::Str(self.signature.as_str()),
784 &expected.as_str(),
785 ))
786 }
787 }
788 }
789 };
790}
791
792impl<'de, T> Visitor<'de> for ValueSeed<'de, T>
793where
794 T: Deserialize<'de>,
795{
796 type Value = Value<'de>;
797
798 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
799 formatter.write_str("a Value value")
800 }
801
802 value_seed_basic_method!(visit_bool, bool);
803 value_seed_basic_method!(visit_i16, i16);
804 value_seed_basic_method!(visit_i64, i64);
805 value_seed_basic_method!(visit_u8, u8);
806 value_seed_basic_method!(visit_u16, u16);
807 value_seed_basic_method!(visit_u32, u32);
808 value_seed_basic_method!(visit_u64, u64);
809 value_seed_basic_method!(visit_f64, f64);
810
811 fn visit_i32<E>(self, value: i32) -> Result<Value<'de>, E>
812 where
813 E: serde::de::Error,
814 {
815 let v = match self.signature.as_bytes().first().ok_or_else(|| {
816 Error::invalid_value(
817 Unexpected::Other("nothing"),
818 &"i32 or fd signature character",
819 )
820 })? {
821 #[cfg(unix)]
822 b'h' => {
823 let fd = unsafe { std::os::fd::BorrowedFd::borrow_raw(value) };
825 Fd::Borrowed(fd).into()
826 }
827 _ => value.into(),
828 };
829
830 Ok(v)
831 }
832
833 #[inline]
834 fn visit_str<E>(self, value: &str) -> Result<Value<'de>, E>
835 where
836 E: serde::de::Error,
837 {
838 self.visit_string(String::from(value))
839 }
840
841 value_seed_str_method!(visit_borrowed_str, &'de str, from_str_unchecked);
842
843 fn visit_seq<V>(self, visitor: V) -> Result<Value<'de>, V::Error>
844 where
845 V: SeqAccess<'de>,
846 {
847 match self.signature.as_bytes().first().ok_or_else(|| {
848 Error::invalid_value(
849 Unexpected::Other("nothing"),
850 &"Array or Struct signature character",
851 )
852 })? {
853 b'a' => self.visit_array(visitor),
855 b'(' => self.visit_struct(visitor),
856 b'v' => self.visit_variant(visitor),
857 b => Err(Error::invalid_value(
858 Unexpected::Char(*b as char),
859 &"a Value signature",
860 )),
861 }
862 }
863
864 fn visit_map<V>(self, mut visitor: V) -> Result<Value<'de>, V::Error>
865 where
866 V: MapAccess<'de>,
867 {
868 if self.signature.len() < 5 {
869 return Err(serde::de::Error::invalid_length(
870 self.signature.len(),
871 &">= 5 characters in dict entry signature",
872 ));
873 }
874 let key_signature = self.signature.slice(2..3);
875 let signature_end = self.signature.len() - 1;
876 let value_signature = self.signature.slice(3..signature_end);
877 let mut dict = Dict::new_full_signature(self.signature.clone());
878
879 while let Some((key, value)) = visitor.next_entry_seed(
880 ValueSeed::<Value<'_>> {
881 signature: key_signature.clone(),
882 phantom: PhantomData,
883 },
884 ValueSeed::<Value<'_>> {
885 signature: value_signature.clone(),
886 phantom: PhantomData,
887 },
888 )? {
889 dict.append(key, value).map_err(Error::custom)?;
890 }
891
892 Ok(Value::Dict(dict))
893 }
894
895 #[cfg(feature = "gvariant")]
896 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
897 where
898 D: Deserializer<'de>,
899 {
900 let visitor = ValueSeed::<T> {
901 signature: self.signature.slice(1..),
902 phantom: PhantomData,
903 };
904
905 deserializer
906 .deserialize_any(visitor)
907 .map(|v| Value::Maybe(Maybe::just_full_signature(v, self.signature)))
908 }
909
910 #[cfg(not(feature = "gvariant"))]
911 fn visit_some<D>(self, _deserializer: D) -> Result<Self::Value, D::Error>
912 where
913 D: Deserializer<'de>,
914 {
915 panic!("`Maybe` type is only supported for GVariant format but it's disabled");
916 }
917
918 #[cfg(feature = "gvariant")]
919 fn visit_none<E>(self) -> Result<Self::Value, E>
920 where
921 E: Error,
922 {
923 let value = Maybe::nothing_full_signature(self.signature);
924
925 Ok(Value::Maybe(value))
926 }
927
928 #[cfg(not(feature = "gvariant"))]
929 fn visit_none<E>(self) -> Result<Self::Value, E>
930 where
931 E: Error,
932 {
933 panic!("`Maybe` type is only supported for GVariant format but it's disabled");
934 }
935}
936
937impl<'de, T> DeserializeSeed<'de> for ValueSeed<'de, T>
938where
939 T: Deserialize<'de>,
940{
941 type Value = Value<'de>;
942
943 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
944 where
945 D: Deserializer<'de>,
946 {
947 deserializer.deserialize_any(self)
948 }
949}
950
951impl<'a> Type for Value<'a> {
952 fn signature() -> Signature<'static> {
953 Signature::from_static_str_unchecked(VARIANT_SIGNATURE_STR)
954 }
955}
956
957impl<'a> TryFrom<&Value<'a>> for Value<'a> {
958 type Error = crate::Error;
959
960 fn try_from(value: &Value<'a>) -> crate::Result<Value<'a>> {
961 value.try_clone()
962 }
963}
964
965#[cfg(test)]
966mod tests {
967 use std::collections::HashMap;
968
969 use super::*;
970
971 #[test]
972 fn value_display() {
973 assert_eq!(
974 Value::new((
975 255_u8,
976 true,
977 -1_i16,
978 65535_u16,
979 -1,
980 1_u32,
981 -9223372036854775808_i64,
982 18446744073709551615_u64,
983 (-1., 1.0, 11000000000., 1.1e-10)
984 ))
985 .to_string(),
986 "(byte 0xff, true, int16 -1, uint16 65535, -1, uint32 1, \
987 int64 -9223372036854775808, uint64 18446744073709551615, \
988 (-1., 1., 11000000000., 0.00000000011))"
989 );
990
991 assert_eq!(
992 Value::new(vec![
993 "", " ", "a", r#"""#, "'", "a'b", "a'\"b", "\\", "\n'\"",
994 ])
995 .to_string(),
996 r#"["", " ", "a", "\"", "'", "a'b", "a'\"b", "\\", "\n'\""]"#
997 );
998 assert_eq!(
999 Value::new(vec![
1000 "\x07\x08\x09\x0A\x0B\x0C\x0D",
1001 "\x7F",
1002 char::from_u32(0xD8000).unwrap().to_string().as_str()
1003 ])
1004 .to_string(),
1005 r#"["\u{7}\u{8}\t\n\u{b}\u{c}\r", "\u{7f}", "\u{d8000}"]"#
1006 );
1007
1008 assert_eq!(
1009 Value::new((
1010 vec![
1011 Signature::from_static_str("").unwrap(),
1012 Signature::from_static_str("(ysa{sd})").unwrap(),
1013 ],
1014 vec![
1015 ObjectPath::from_static_str("/").unwrap(),
1016 ObjectPath::from_static_str("/a/very/looooooooooooooooooooooooo0000o0ng/path")
1017 .unwrap(),
1018 ],
1019 vec![
1020 Value::new(0_u8),
1021 Value::new((Value::new(51), Value::new(Value::new(1_u32)))),
1022 ]
1023 ))
1024 .to_string(),
1025 "([signature \"\", \"(ysa{sd})\"], \
1026 [objectpath \"/\", \"/a/very/looooooooooooooooooooooooo0000o0ng/path\"], \
1027 [<byte 0x00>, <(<51>, <<uint32 1>>)>])"
1028 );
1029
1030 assert_eq!(Value::new(vec![] as Vec<Vec<i64>>).to_string(), "@aax []");
1031 assert_eq!(
1032 Value::new(vec![
1033 vec![0_i16, 1_i16],
1034 vec![2_i16, 3_i16],
1035 vec![4_i16, 5_i16]
1036 ])
1037 .to_string(),
1038 "[[int16 0, 1], [2, 3], [4, 5]]"
1039 );
1040 assert_eq!(
1041 Value::new(vec![
1042 b"Hello".to_vec(),
1043 b"Hell\0o".to_vec(),
1044 b"H\0ello\0".to_vec(),
1045 b"Hello\0".to_vec(),
1046 b"\0".to_vec(),
1047 b" \0".to_vec(),
1048 b"'\0".to_vec(),
1049 b"\n'\"\0".to_vec(),
1050 b"\\\0".to_vec(),
1051 ])
1052 .to_string(),
1053 "[[byte 0x48, 0x65, 0x6c, 0x6c, 0x6f], \
1054 [0x48, 0x65, 0x6c, 0x6c, 0x00, 0x6f], \
1055 [0x48, 0x00, 0x65, 0x6c, 0x6c, 0x6f, 0x00], \
1056 b\"Hello\", b\"\", b\" \", b\"'\", b\"\\n'\\\"\", b\"\\\\\"]"
1057 );
1058
1059 assert_eq!(
1060 Value::new(HashMap::<bool, bool>::new()).to_string(),
1061 "@a{bb} {}"
1062 );
1063 assert_eq!(
1064 Value::new(vec![(true, 0_i64)].into_iter().collect::<HashMap<_, _>>()).to_string(),
1065 "{true: int64 0}",
1066 );
1067 let val = Value::new(
1069 vec![(32_u16, 64_i64), (100_u16, 200_i64)]
1070 .into_iter()
1071 .collect::<HashMap<_, _>>(),
1072 )
1073 .to_string();
1074 assert!(val.starts_with('{'));
1075 assert!(val.ends_with('}'));
1076 assert_eq!(val.matches("uint16").count(), 1);
1077 assert_eq!(val.matches("int64").count(), 1);
1078
1079 let items_str = val.split(", ").collect::<Vec<_>>();
1080 assert_eq!(items_str.len(), 2);
1081 assert!(items_str
1082 .iter()
1083 .any(|str| str.contains("32") && str.contains(": ") && str.contains("64")));
1084 assert!(items_str
1085 .iter()
1086 .any(|str| str.contains("100") && str.contains(": ") && str.contains("200")));
1087
1088 assert_eq!(Value::new(Structure::default()).to_string(), "()");
1089 assert_eq!(
1090 Value::new(((true,), (true, false), (true, true, false))).to_string(),
1091 "((true,), (true, false), (true, true, false))"
1092 );
1093
1094 #[cfg(any(feature = "gvariant", feature = "option-as-array"))]
1095 {
1096 #[cfg(unix)]
1097 use std::os::fd::BorrowedFd;
1098
1099 #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1100 let s = "((@mn 0, @mmn 0, @mmmn 0), \
1101 (@mn nothing, @mmn just nothing, @mmmn just just nothing), \
1102 (@mmn nothing, @mmmn just nothing))";
1103 #[cfg(feature = "option-as-array")]
1104 let s = "(([int16 0], [[int16 0]], [[[int16 0]]]), \
1105 (@an [], [@an []], [[@an []]]), \
1106 (@aan [], [@aan []]))";
1107 assert_eq!(
1108 Value::new((
1109 (Some(0_i16), Some(Some(0_i16)), Some(Some(Some(0_i16))),),
1110 (None::<i16>, Some(None::<i16>), Some(Some(None::<i16>)),),
1111 (None::<Option<i16>>, Some(None::<Option<i16>>)),
1112 ))
1113 .to_string(),
1114 s,
1115 );
1116
1117 #[cfg(unix)]
1118 assert_eq!(
1119 Value::new(vec![
1120 Fd::from(unsafe { BorrowedFd::borrow_raw(0) }),
1121 Fd::from(unsafe { BorrowedFd::borrow_raw(-100) })
1122 ])
1123 .to_string(),
1124 "[handle 0, -100]"
1125 );
1126
1127 #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1128 let s = "(@mb nothing, @mb nothing, \
1129 @ma{sv} {\"size\": <(800, 600)>}, \
1130 [<1>, <{\"dimension\": <([2.4, 1.], \
1131 @mmn 200, <(byte 0x03, \"Hello!\")>)>}>], \
1132 7777, objectpath \"/\", 8888)";
1133 #[cfg(feature = "option-as-array")]
1134 let s = "(@ab [], @ab [], [{\"size\": <(800, 600)>}], \
1135 [<1>, <{\"dimension\": <([2.4, 1.], [[int16 200]], \
1136 <(byte 0x03, \"Hello!\")>)>}>], 7777, objectpath \"/\", 8888)";
1137 assert_eq!(
1138 Value::new((
1139 None::<bool>,
1140 None::<bool>,
1141 Some(
1142 vec![("size", Value::new((800, 600)))]
1143 .into_iter()
1144 .collect::<HashMap<_, _>>()
1145 ),
1146 vec![
1147 Value::new(1),
1148 Value::new(
1149 vec![(
1150 "dimension",
1151 Value::new((
1152 vec![2.4, 1.],
1153 Some(Some(200_i16)),
1154 Value::new((3_u8, "Hello!"))
1155 ))
1156 )]
1157 .into_iter()
1158 .collect::<HashMap<_, _>>()
1159 )
1160 ],
1161 7777,
1162 ObjectPath::from_static_str("/").unwrap(),
1163 8888
1164 ))
1165 .to_string(),
1166 s,
1167 );
1168 }
1169 }
1170}