zvariant/
lib.rs

1#![allow(clippy::unusual_byte_groupings)]
2#![deny(rust_2018_idioms)]
3#![doc(
4    html_logo_url = "https://raw.githubusercontent.com/dbus2/zbus/9f7a90d2b594ddc48b7a5f39fda5e00cd56a7dfb/logo.png"
5)]
6#![doc = include_str!("../README.md")]
7#![doc(test(attr(
8    warn(unused),
9    deny(warnings),
10    allow(dead_code),
11    // W/o this, we seem to get some bogus warning about `extern crate zbus`.
12    allow(unused_extern_crates),
13)))]
14#![cfg_attr(test, recursion_limit = "256")]
15
16#[macro_use]
17mod utils;
18pub use utils::*;
19
20mod array;
21pub use array::*;
22
23mod basic;
24pub use basic::*;
25
26mod dict;
27pub use dict::*;
28
29#[deprecated(since = "4.0.0", note = "Use `serialized::Context` instead")]
30#[doc(hidden)]
31pub type EncodingContext = serialized::Context;
32#[deprecated(since = "4.0.0", note = "Use `serialized::Format` instead")]
33#[doc(hidden)]
34pub type EncodingFormat = serialized::Format;
35
36pub mod serialized;
37
38#[cfg(unix)]
39mod fd;
40#[cfg(unix)]
41pub use fd::*;
42
43mod object_path;
44pub use crate::object_path::*;
45
46mod ser;
47pub use ser::*;
48
49mod de;
50
51pub mod dbus;
52#[cfg(feature = "gvariant")]
53pub mod gvariant;
54
55mod signature;
56pub use crate::signature::*;
57
58mod complete_type;
59pub use complete_type::*;
60
61mod str;
62pub use crate::str::*;
63
64mod structure;
65pub use crate::structure::*;
66
67#[cfg(feature = "gvariant")]
68mod maybe;
69#[cfg(feature = "gvariant")]
70pub use crate::maybe::*;
71
72mod optional;
73pub use crate::optional::*;
74
75mod value;
76pub use value::*;
77
78mod serialize_value;
79pub use serialize_value::*;
80
81mod deserialize_value;
82pub use deserialize_value::*;
83
84mod error;
85pub use error::*;
86
87#[macro_use]
88mod r#type;
89pub use r#type::*;
90
91mod tuple;
92pub use tuple::*;
93
94mod from_value;
95
96mod into_value;
97
98mod owned_value;
99pub use owned_value::*;
100
101#[cfg(feature = "gvariant")]
102mod framing_offset_size;
103#[cfg(feature = "gvariant")]
104mod framing_offsets;
105mod signature_parser;
106
107mod container_depths;
108
109pub use zvariant_derive::{DeserializeDict, OwnedValue, SerializeDict, Type, Value};
110
111// Required for the macros to function within this crate.
112extern crate self as zvariant;
113
114// Macro support module, not part of the public API.
115#[doc(hidden)]
116pub mod export {
117    pub use serde;
118}
119
120// Re-export all of the `endi` API for ease of use.
121pub use endi::*;
122
123#[cfg(test)]
124#[allow(clippy::disallowed_names)]
125mod tests {
126    use std::{
127        collections::{BTreeMap, HashMap},
128        net::{IpAddr, Ipv4Addr, Ipv6Addr},
129    };
130
131    #[cfg(feature = "arrayvec")]
132    use arrayvec::{ArrayString, ArrayVec};
133    #[cfg(feature = "arrayvec")]
134    use std::str::FromStr;
135
136    #[cfg(feature = "gvariant")]
137    use glib::{variant::FromVariant, Bytes, Variant};
138    use serde::{Deserialize, Serialize};
139
140    use crate::{serialized::Data, to_bytes, to_bytes_for_signature, MaxDepthExceeded};
141
142    #[cfg(unix)]
143    use crate::Fd;
144    use crate::{
145        serialized::{Context, Format},
146        Array, Basic, DeserializeDict, DeserializeValue, Dict, Error, ObjectPath, Result,
147        SerializeDict, SerializeValue, Signature, Str, Structure, Type, Value, BE, LE,
148        NATIVE_ENDIAN,
149    };
150
151    // Test through both generic and specific API (wrt byte order)
152    macro_rules! basic_type_test {
153        ($endian:expr, $format:ident, $test_value:expr, $expected_len:expr, $expected_ty:ty, $align:literal) => {{
154            // Lie that we're starting at byte 1 in the overall message to test padding
155            let ctxt = Context::new(Format::$format, $endian, 1);
156            let encoded = to_bytes(ctxt, &$test_value).unwrap();
157            let padding = crate::padding_for_n_bytes(1, $align);
158            assert_eq!(
159                encoded.len(),
160                $expected_len + padding,
161                "invalid encoding using `to_bytes`"
162            );
163            let (decoded, parsed): ($expected_ty, _) = encoded.deserialize().unwrap();
164            assert!(decoded == $test_value, "invalid decoding");
165            assert!(parsed == encoded.len(), "invalid parsing");
166
167            // Now encode w/o padding
168            let ctxt = Context::new(Format::$format, $endian, 0);
169            let encoded = to_bytes(ctxt, &$test_value).unwrap();
170            assert_eq!(
171                encoded.len(),
172                $expected_len,
173                "invalid encoding using `to_bytes`"
174            );
175
176            encoded
177        }};
178        ($endian:expr, $format:ident, $test_value:expr, $expected_len:expr, $expected_ty:ty, $align:literal, $kind:ident, $expected_value_len:expr) => {{
179            let encoded = basic_type_test!(
180                $endian,
181                $format,
182                $test_value,
183                $expected_len,
184                $expected_ty,
185                $align
186            );
187
188            // As Value
189            let v: Value<'_> = $test_value.into();
190            assert_eq!(v.value_signature(), <$expected_ty>::SIGNATURE_STR);
191            assert_eq!(v, Value::$kind($test_value));
192            value_test!(LE, $format, v, $expected_value_len);
193
194            let v: $expected_ty = v.try_into().unwrap();
195            assert_eq!(v, $test_value);
196
197            encoded
198        }};
199    }
200
201    macro_rules! value_test {
202        ($endian:expr, $format:ident, $test_value:expr, $expected_len:expr) => {{
203            let ctxt = Context::new(Format::$format, $endian, 0);
204            let encoded = to_bytes(ctxt, &$test_value).unwrap();
205            assert_eq!(
206                encoded.len(),
207                $expected_len,
208                "invalid encoding using `to_bytes`"
209            );
210            let (decoded, parsed): (Value<'_>, _) = encoded.deserialize().unwrap();
211            assert!(decoded == $test_value, "invalid decoding");
212            assert!(parsed == encoded.len(), "invalid parsing");
213
214            encoded
215        }};
216    }
217
218    fn f64_type_test(
219        format: Format,
220        value: f64,
221        expected_len: usize,
222        expected_value_len: usize,
223    ) -> crate::serialized::Data<'static, 'static> {
224        // Lie that we're starting at byte 1 in the overall message to test padding
225        let ctxt = Context::new(format, NATIVE_ENDIAN, 1);
226        let encoded = to_bytes(ctxt, &value).unwrap();
227        let padding = crate::padding_for_n_bytes(1, 8);
228        assert_eq!(
229            encoded.len(),
230            expected_len + padding,
231            "invalid encoding using `to_bytes`"
232        );
233
234        let decoded: f64 = encoded.deserialize().unwrap().0;
235        assert!(
236            (decoded - value).abs() < f64::EPSILON,
237            "invalid decoding using `from_slice`"
238        );
239
240        // Now encode w/o padding
241        let ctxt = Context::new(format, NATIVE_ENDIAN, 0);
242        let encoded = to_bytes(ctxt, &value).unwrap();
243        assert_eq!(
244            encoded.len(),
245            expected_len,
246            "invalid encoding using `to_bytes`"
247        );
248
249        f64_type_test_as_value(format, value, expected_value_len);
250        encoded
251    }
252
253    fn f64_type_test_as_value(format: Format, value: f64, expected_value_len: usize) {
254        let v: Value<'_> = value.into();
255        assert_eq!(v.value_signature(), f64::SIGNATURE_STR);
256        assert_eq!(v, Value::F64(value));
257        f64_value_test(format, v.try_clone().unwrap(), expected_value_len);
258        let v: f64 = v.try_into().unwrap();
259        assert!((v - value).abs() < f64::EPSILON);
260    }
261
262    fn f64_value_test(format: Format, v: Value<'_>, expected_value_len: usize) {
263        let ctxt = Context::new(format, LE, 0);
264        let encoded = to_bytes(ctxt, &v).unwrap();
265        assert_eq!(
266            encoded.len(),
267            expected_value_len,
268            "invalid encoding using `to_bytes`"
269        );
270        let decoded: Value<'_> = encoded.deserialize().unwrap().0;
271        assert!(decoded == v, "invalid decoding using `from_slice`");
272    }
273
274    /// Decode with gvariant and compare with expected value (if provided).
275    #[cfg(feature = "gvariant")]
276    fn decode_with_gvariant<B, T>(encoded: B, expected_value: Option<T>) -> T
277    where
278        B: AsRef<[u8]> + Send + 'static,
279        T: glib::variant::FromVariant + std::fmt::Debug + PartialEq,
280    {
281        let bytes = Bytes::from_owned(encoded);
282        let gv = Variant::from_bytes::<T>(&bytes);
283        let v = gv.get::<T>().unwrap();
284        if let Some(expected_value) = expected_value {
285            assert_eq!(v, expected_value);
286        }
287
288        v
289    }
290
291    /// Decode a number with gvariant and compare with expected value (if provided).
292    ///
293    /// `expected_value` is a tuple of (little endian value, big endian value).
294    #[cfg(feature = "gvariant")]
295    fn decode_num_with_gvariant<B, T>(encoded: B, expected_value: Option<(T, T)>) -> T
296    where
297        B: AsRef<[u8]> + Send + 'static,
298        T: glib::variant::FromVariant + std::fmt::Debug + PartialEq,
299    {
300        #[allow(unused_variables)]
301        let expected_value = expected_value.map(|(le, be)| {
302            #[cfg(target_endian = "little")]
303            {
304                le
305            }
306
307            #[cfg(target_endian = "big")]
308            {
309                be
310            }
311        });
312        decode_with_gvariant(encoded, expected_value)
313    }
314
315    // All fixed size types have the same encoding in DBus and GVariant formats.
316    //
317    // NB: Value (i-e VARIANT type) isn't a fixed size type.
318
319    #[test]
320    fn u8_value() {
321        let encoded = basic_type_test!(LE, DBus, 77_u8, 1, u8, 1, U8, 4);
322        assert_eq!(encoded.len(), 1);
323        #[cfg(feature = "gvariant")]
324        {
325            decode_num_with_gvariant::<_, u8>(encoded, Some((77u8, 77u8)));
326            basic_type_test!(LE, GVariant, 77_u8, 1, u8, 1, U8, 3);
327        }
328    }
329
330    #[test]
331    fn i8_value() {
332        basic_type_test!(LE, DBus, 77_i8, 2, i8, 2);
333        #[cfg(feature = "gvariant")]
334        basic_type_test!(LE, GVariant, 77_i8, 2, i8, 2);
335    }
336
337    #[cfg(unix)]
338    macro_rules! fd_value_test {
339        ($endian:expr, $format:ident, $test_value:expr, $expected_len:expr, $align:literal, $expected_value_len:expr) => {{
340            use std::os::fd::AsFd;
341
342            // Lie that we're starting at byte 1 in the overall message to test padding
343            let ctxt = Context::new(Format::$format, $endian, 1);
344            let encoded = to_bytes(ctxt, &$test_value).unwrap();
345            let padding = crate::padding_for_n_bytes(1, $align);
346            assert_eq!(
347                encoded.len(),
348                $expected_len + padding,
349                "invalid encoding using `to_bytes`"
350            );
351            #[cfg(unix)]
352            let (_, parsed): (Fd<'_>, _) = encoded.deserialize().unwrap();
353            assert!(
354                parsed == encoded.len(),
355                "invalid parsing using `from_slice`"
356            );
357
358            // Now encode w/o padding
359            let ctxt = Context::new(Format::$format, $endian, 0);
360            let encoded = to_bytes(ctxt, &$test_value).unwrap();
361            assert_eq!(
362                encoded.len(),
363                $expected_len,
364                "invalid encoding using `to_bytes`"
365            );
366
367            // As Value
368            let v: Value<'_> = $test_value.into();
369            assert_eq!(v.value_signature(), Fd::SIGNATURE_STR);
370            assert_eq!(v, Value::Fd($test_value));
371            let encoded = to_bytes(ctxt, &v).unwrap();
372            assert_eq!(encoded.fds().len(), 1, "invalid encoding using `to_bytes`");
373            assert_eq!(
374                encoded.len(),
375                $expected_value_len,
376                "invalid encoding using `to_bytes`"
377            );
378            let (decoded, parsed): (Value<'_>, _) = encoded.deserialize().unwrap();
379            assert_eq!(
380                decoded,
381                Fd::from(encoded.fds()[0].as_fd()).into(),
382                "invalid decoding using `from_slice`"
383            );
384            assert_eq!(parsed, encoded.len(), "invalid parsing using `from_slice`");
385
386            let v: Fd<'_> = v.try_into().unwrap();
387            assert_eq!(v, $test_value);
388        }};
389    }
390
391    #[cfg(unix)]
392    #[test]
393    fn fd_value() {
394        use std::os::fd::AsFd;
395
396        let stdout = std::io::stdout();
397        let fd = stdout.as_fd();
398        fd_value_test!(LE, DBus, Fd::from(fd), 4, 4, 8);
399        #[cfg(feature = "gvariant")]
400        fd_value_test!(LE, GVariant, Fd::from(fd), 4, 4, 6);
401    }
402
403    #[test]
404    fn u16_value() {
405        let encoded = basic_type_test!(BE, DBus, 0xABBA_u16, 2, u16, 2, U16, 6);
406        assert_eq!(encoded.len(), 2);
407        #[cfg(feature = "gvariant")]
408        {
409            decode_num_with_gvariant::<_, u16>(encoded, Some((0xBAAB_u16, 0xABBA_u16)));
410            basic_type_test!(BE, GVariant, 0xABBA_u16, 2, u16, 2, U16, 4);
411        }
412    }
413
414    #[test]
415    fn i16_value() {
416        let encoded = basic_type_test!(BE, DBus, -0xAB0_i16, 2, i16, 2, I16, 6);
417        assert_eq!(LE.read_i16(&encoded), 0x50F5_i16);
418        #[cfg(feature = "gvariant")]
419        {
420            decode_num_with_gvariant::<_, i16>(encoded, Some((0x50F5_i16, -0xAB0_i16)));
421            basic_type_test!(BE, GVariant, -0xAB0_i16, 2, i16, 2, I16, 4);
422        }
423    }
424
425    #[test]
426    fn u32_value() {
427        let encoded = basic_type_test!(BE, DBus, 0xABBA_ABBA_u32, 4, u32, 4, U32, 8);
428        assert_eq!(encoded.len(), 4);
429        #[cfg(feature = "gvariant")]
430        {
431            decode_num_with_gvariant::<_, u32>(encoded, Some((0xBAAB_BAAB_u32, 0xABBA_ABBA_u32)));
432            basic_type_test!(BE, GVariant, 0xABBA_ABBA_u32, 4, u32, 4, U32, 6);
433        }
434    }
435
436    #[test]
437    fn i32_value() {
438        let encoded = basic_type_test!(BE, DBus, -0xABBA_AB0_i32, 4, i32, 4, I32, 8);
439        assert_eq!(LE.read_i32(&encoded), 0x5055_44F5_i32);
440        #[cfg(feature = "gvariant")]
441        {
442            decode_num_with_gvariant::<_, i32>(encoded, Some((0x5055_44F5_i32, -0xABBA_AB0_i32)));
443            basic_type_test!(BE, GVariant, -0xABBA_AB0_i32, 4, i32, 4, I32, 6);
444        }
445    }
446
447    // u64 is covered by `value_value` test below
448
449    #[test]
450    fn i64_value() {
451        let encoded = basic_type_test!(BE, DBus, -0xABBA_ABBA_ABBA_AB0_i64, 8, i64, 8, I64, 16);
452        assert_eq!(LE.read_i64(&encoded), 0x5055_4455_4455_44F5_i64);
453        #[cfg(feature = "gvariant")]
454        {
455            decode_num_with_gvariant::<_, i64>(
456                encoded,
457                Some((0x5055_4455_4455_44F5_i64, -0xABBA_ABBA_ABBA_AB0_i64)),
458            );
459            basic_type_test!(BE, GVariant, -0xABBA_ABBA_ABBA_AB0_i64, 8, i64, 8, I64, 10);
460        }
461    }
462
463    #[test]
464    fn f64_value() {
465        let encoded = f64_type_test(Format::DBus, 99999.99999_f64, 8, 16);
466        assert!((NATIVE_ENDIAN.read_f64(&encoded) - 99999.99999_f64).abs() < f64::EPSILON);
467        #[cfg(feature = "gvariant")]
468        {
469            assert!(
470                (decode_with_gvariant::<_, f64>(encoded, None) - 99999.99999_f64).abs()
471                    < f64::EPSILON
472            );
473            f64_type_test(Format::GVariant, 99999.99999_f64, 8, 10);
474        }
475    }
476
477    #[test]
478    fn str_value() {
479        let string = String::from("hello world");
480        basic_type_test!(LE, DBus, string, 16, String, 4);
481        basic_type_test!(LE, DBus, string, 16, &str, 4);
482
483        // GVariant format now
484        #[cfg(feature = "gvariant")]
485        {
486            let encoded = basic_type_test!(LE, GVariant, string, 12, String, 1);
487            decode_with_gvariant::<_, String>(encoded, Some(String::from("hello world")));
488        }
489
490        let string = "hello world";
491        basic_type_test!(LE, DBus, string, 16, &str, 4);
492        basic_type_test!(LE, DBus, string, 16, String, 4);
493
494        // As Value
495        let v: Value<'_> = string.into();
496        assert_eq!(v.value_signature(), "s");
497        assert_eq!(v, Value::new("hello world"));
498        value_test!(LE, DBus, v, 20);
499        #[cfg(feature = "gvariant")]
500        {
501            let encoded = value_test!(LE, GVariant, v, 14);
502
503            // Check encoding against GLib
504            let bytes = Bytes::from_owned(encoded);
505            let gv = Variant::from_bytes::<Variant>(&bytes);
506            let variant = gv.as_variant().unwrap();
507            assert_eq!(variant.str().unwrap(), "hello world");
508        }
509
510        let v: String = v.try_into().unwrap();
511        assert_eq!(v, "hello world");
512
513        // Check for interior null bytes which are not allowed
514        let ctxt = Context::new_dbus(LE, 0);
515        assert!(Data::new(&b"\x0b\0\0\0hello\0world\0"[..], ctxt)
516            .deserialize::<&str>()
517            .is_err());
518        assert!(to_bytes(ctxt, &"hello\0world").is_err());
519
520        // GVariant format doesn't allow null bytes either
521        #[cfg(feature = "gvariant")]
522        {
523            let ctxt = Context::new_gvariant(LE, 0);
524            assert!(Data::new(&b"\x0b\0\0\0hello\0world\0"[..], ctxt)
525                .deserialize::<&str>()
526                .is_err());
527            assert!(to_bytes(ctxt, &"hello\0world").is_err());
528        }
529
530        // Characters are treated as strings
531        basic_type_test!(LE, DBus, 'c', 6, char, 4);
532        #[cfg(feature = "gvariant")]
533        basic_type_test!(LE, GVariant, 'c', 2, char, 1);
534
535        // As Value
536        let v: Value<'_> = "c".into();
537        assert_eq!(v.value_signature(), "s");
538        let ctxt = Context::new_dbus(LE, 0);
539        let encoded = to_bytes(ctxt, &v).unwrap();
540        assert_eq!(encoded.len(), 10);
541        let (v, _) = encoded.deserialize::<Value<'_>>().unwrap();
542        assert_eq!(v, Value::new("c"));
543    }
544
545    #[cfg(feature = "arrayvec")]
546    #[test]
547    fn array_string_value() {
548        let s = ArrayString::<32>::from_str("hello world!").unwrap();
549        let ctxt = Context::new_dbus(LE, 0);
550        let encoded = to_bytes(ctxt, &s).unwrap();
551        assert_eq!(encoded.len(), 17);
552        let decoded: ArrayString<32> = encoded.deserialize().unwrap().0;
553        assert_eq!(&decoded, "hello world!");
554    }
555
556    #[cfg(feature = "heapless")]
557    #[test]
558    fn heapless_string_value() {
559        use heapless::String;
560
561        let s = String::<32>::try_from("hello world!").unwrap();
562        let ctxt = Context::new_dbus(LE, 0);
563        let encoded = to_bytes(ctxt, &s).unwrap();
564        assert_eq!(encoded.len(), 17);
565        let decoded: String<32> = encoded.deserialize().unwrap().0;
566        assert_eq!(&decoded, "hello world!");
567    }
568
569    #[test]
570    fn signature_value() {
571        let sig = Signature::try_from("yys").unwrap();
572        basic_type_test!(LE, DBus, sig, 5, Signature<'_>, 1);
573
574        #[cfg(feature = "gvariant")]
575        {
576            let encoded = basic_type_test!(LE, GVariant, sig, 4, Signature<'_>, 1);
577            decode_with_gvariant::<_, String>(encoded, Some(String::from("yys")));
578        }
579
580        // As Value
581        let v: Value<'_> = sig.into();
582        assert_eq!(v.value_signature(), "g");
583        let encoded = value_test!(LE, DBus, v, 8);
584        let v = encoded.deserialize::<Value<'_>>().unwrap().0;
585        assert_eq!(v, Value::Signature(Signature::try_from("yys").unwrap()));
586
587        // GVariant format now
588        #[cfg(feature = "gvariant")]
589        {
590            let encoded = value_test!(LE, GVariant, v, 6);
591            let v = encoded.deserialize::<Value<'_>>().unwrap().0;
592            assert_eq!(v, Value::Signature(Signature::try_from("yys").unwrap()));
593        }
594    }
595
596    #[test]
597    fn object_path_value() {
598        let o = ObjectPath::try_from("/hello/world").unwrap();
599        basic_type_test!(LE, DBus, o, 17, ObjectPath<'_>, 4);
600
601        #[cfg(feature = "gvariant")]
602        {
603            let encoded = basic_type_test!(LE, GVariant, o, 13, ObjectPath<'_>, 1);
604            decode_with_gvariant::<_, String>(encoded, Some(String::from("/hello/world")));
605        }
606
607        // As Value
608        let v: Value<'_> = o.into();
609        assert_eq!(v.value_signature(), "o");
610        let encoded = value_test!(LE, DBus, v, 21);
611        let v = encoded.deserialize::<Value<'_>>().unwrap().0;
612        assert_eq!(
613            v,
614            Value::ObjectPath(ObjectPath::try_from("/hello/world").unwrap())
615        );
616
617        // GVariant format now
618        #[cfg(feature = "gvariant")]
619        {
620            let encoded = value_test!(LE, GVariant, v, 15);
621            let v = encoded.deserialize::<Value<'_>>().unwrap().0;
622            assert_eq!(
623                v,
624                Value::ObjectPath(ObjectPath::try_from("/hello/world").unwrap())
625            );
626        }
627    }
628
629    #[cfg(unix)]
630    #[test]
631    fn unit_fds() {
632        let ctxt = Context::new_dbus(BE, 0);
633        let encoded = to_bytes(ctxt, &()).unwrap();
634        assert_eq!(encoded.len(), 0, "invalid encoding using `to_bytes`");
635        let _: () = encoded
636            .deserialize()
637            .expect("invalid decoding using `from_slice`")
638            .0;
639    }
640
641    #[test]
642    fn unit() {
643        let ctxt = Context::new_dbus(BE, 0);
644        let encoded = to_bytes(ctxt, &()).unwrap();
645        assert_eq!(encoded.len(), 0, "invalid encoding using `to_bytes`");
646        let _: () = encoded
647            .deserialize()
648            .expect("invalid decoding using `from_slice`")
649            .0;
650    }
651
652    #[test]
653    fn array_value() {
654        // Let's use D-Bus/GVariant terms
655
656        //
657        // Array of u8
658        //
659        // First a normal Rust array that is actually serialized as a struct (thank you Serde!)
660        assert_eq!(<[u8; 2]>::signature(), "(yy)");
661        let ay = [77u8, 88];
662        let ctxt = Context::new_dbus(LE, 0);
663        let encoded = to_bytes(ctxt, &ay).unwrap();
664        assert_eq!(encoded.len(), 2);
665        let decoded: [u8; 2] = encoded.deserialize().unwrap().0;
666        assert_eq!(&decoded, &[77u8, 88]);
667
668        // Then rest of the tests just use ArrayVec, heapless::Vec or Vec
669        #[cfg(feature = "arrayvec")]
670        let ay = ArrayVec::from([77u8, 88]);
671        #[cfg(all(not(feature = "arrayvec"), feature = "heapless"))]
672        let ay = heapless::Vec::<_, 2>::from_slice(&[77u8, 88]).unwrap();
673        #[cfg(all(not(feature = "arrayvec"), not(feature = "heapless")))]
674        let ay = vec![77u8, 88];
675        let ctxt = Context::new_dbus(LE, 0);
676        let encoded = to_bytes(ctxt, &ay).unwrap();
677        assert_eq!(encoded.len(), 6);
678
679        #[cfg(feature = "arrayvec")]
680        let decoded: ArrayVec<u8, 2> = encoded.deserialize().unwrap().0;
681        #[cfg(all(not(feature = "arrayvec"), feature = "heapless"))]
682        let decoded: heapless::Vec<u8, 2> = encoded.deserialize().unwrap().0;
683        #[cfg(all(not(feature = "arrayvec"), not(feature = "heapless")))]
684        let decoded: Vec<u8> = encoded.deserialize().unwrap().0;
685        assert_eq!(&decoded.as_slice(), &[77u8, 88]);
686
687        // GVariant format now
688        #[cfg(feature = "gvariant")]
689        {
690            let ctxt = Context::new_gvariant(LE, 0);
691            let gv_encoded = to_bytes(ctxt, &ay).unwrap();
692            assert_eq!(gv_encoded.len(), 2);
693
694            // Check encoding against GLib
695            let bytes = Bytes::from_owned(gv_encoded);
696            let variant = Variant::from_bytes::<&[u8]>(&bytes);
697            assert_eq!(variant.n_children(), 2);
698            assert_eq!(variant.child_value(0).get::<u8>().unwrap(), 77);
699            assert_eq!(variant.child_value(1).get::<u8>().unwrap(), 88);
700        }
701        let ctxt = Context::new_dbus(LE, 0);
702
703        // As Value
704        let v: Value<'_> = ay[..].into();
705        assert_eq!(v.value_signature(), "ay");
706        let encoded = to_bytes(ctxt, &v).unwrap();
707        assert_eq!(encoded.len(), 10);
708        let v = encoded.deserialize::<Value<'_>>().unwrap().0;
709        if let Value::Array(array) = v {
710            assert_eq!(*array.element_signature(), "y");
711            assert_eq!(array.len(), 2);
712            assert_eq!(array.get(0).unwrap(), Some(77u8));
713            assert_eq!(array.get(1).unwrap(), Some(88u8));
714        } else {
715            panic!();
716        }
717
718        // Now try as Vec
719        let vec = ay.to_vec();
720        let encoded = to_bytes(ctxt, &vec).unwrap();
721        assert_eq!(encoded.len(), 6);
722
723        // Vec as Value
724        let v: Value<'_> = Array::from(&vec).into();
725        assert_eq!(v.value_signature(), "ay");
726        let encoded = to_bytes(ctxt, &v).unwrap();
727        assert_eq!(encoded.len(), 10);
728
729        // Empty array
730        let at: Vec<u64> = vec![];
731        let encoded = to_bytes(ctxt, &at).unwrap();
732        assert_eq!(encoded.len(), 8);
733
734        // GVariant format now
735        #[cfg(feature = "gvariant")]
736        {
737            let ctxt = Context::new_gvariant(LE, 0);
738            let gv_encoded = to_bytes(ctxt, &at).unwrap();
739            assert_eq!(gv_encoded.len(), 0);
740            let at = encoded.deserialize::<Vec<u64>>().unwrap().0;
741            assert_eq!(at.len(), 0);
742        }
743        let ctxt = Context::new_dbus(LE, 0);
744
745        // As Value
746        let v: Value<'_> = at[..].into();
747        assert_eq!(v.value_signature(), "at");
748        let encoded = to_bytes(ctxt, &v).unwrap();
749        assert_eq!(encoded.len(), 8);
750        let v = encoded.deserialize::<Value<'_>>().unwrap().0;
751        if let Value::Array(array) = v {
752            assert_eq!(*array.element_signature(), "t");
753            assert_eq!(array.len(), 0);
754        } else {
755            panic!();
756        }
757
758        // GVariant format now
759        #[cfg(feature = "gvariant")]
760        {
761            let ctxt = Context::new_gvariant(LE, 0);
762            let v: Value<'_> = at[..].into();
763            let gv_encoded = to_bytes(ctxt, &v).unwrap();
764            assert_eq!(gv_encoded.len(), 3);
765            let v = gv_encoded.deserialize::<Value<'_>>().unwrap().0;
766            if let Value::Array(array) = v {
767                assert_eq!(*array.element_signature(), "t");
768                assert_eq!(array.len(), 0);
769            } else {
770                panic!();
771            }
772
773            // Check encoding against GLib
774            let bytes = Bytes::from_owned(gv_encoded);
775            let variant = Variant::from_bytes::<&[&str]>(&bytes);
776            assert_eq!(variant.n_children(), 0);
777        }
778        let ctxt = Context::new_dbus(LE, 0);
779
780        //
781        // Array of strings
782        //
783        // Can't use 'as' as it's a keyword
784        let as_ = vec!["Hello", "World", "Now", "Bye!"];
785        let encoded = to_bytes(ctxt, &as_).unwrap();
786        assert_eq!(encoded.len(), 45);
787        let decoded = encoded.deserialize::<Vec<&str>>().unwrap().0;
788        assert_eq!(decoded.len(), 4);
789        assert_eq!(decoded[0], "Hello");
790        assert_eq!(decoded[1], "World");
791
792        let decoded = encoded.deserialize::<Vec<String>>().unwrap().0;
793        assert_eq!(decoded.as_slice(), as_.as_slice());
794
795        // Decode just the second string
796        let slice = encoded.slice(14..);
797        let decoded: &str = slice.deserialize().unwrap().0;
798        assert_eq!(decoded, "World");
799
800        // As Value
801        let v: Value<'_> = as_[..].into();
802        assert_eq!(v.value_signature(), "as");
803        let encoded = to_bytes(ctxt, &v).unwrap();
804        assert_eq!(encoded.len(), 49);
805        let v = encoded.deserialize().unwrap().0;
806        if let Value::Array(array) = v {
807            assert_eq!(*array.element_signature(), "s");
808            assert_eq!(array.len(), 4);
809            assert_eq!(array[0], Value::new("Hello"));
810            assert_eq!(array[1], Value::new("World"));
811        } else {
812            panic!();
813        }
814
815        let v: Value<'_> = as_[..].into();
816        let a: Array<'_> = v.try_into().unwrap();
817        let _ve: Vec<String> = a.try_into().unwrap();
818
819        // GVariant format now
820        #[cfg(feature = "gvariant")]
821        {
822            let ctxt = Context::new_gvariant(LE, 0);
823            let v: Value<'_> = as_[..].into();
824            let gv_encoded = to_bytes(ctxt, &v).unwrap();
825            assert_eq!(gv_encoded.len(), 28);
826
827            // Check encoding against GLib
828            let bytes = Bytes::from_owned(gv_encoded);
829            let variant = Variant::from_bytes::<Variant>(&bytes);
830            assert_eq!(variant.n_children(), 1);
831            let decoded: Vec<String> = variant.child_value(0).get().unwrap();
832            assert_eq!(decoded[0], "Hello");
833            assert_eq!(decoded[1], "World");
834        }
835
836        // Array of Struct, which in turn containin an Array (We gotta go deeper!)
837        // Signature: "a(yu(xbxas)s)");
838        let ar = vec![(
839            // top-most simple fields
840            u8::MAX,
841            u32::MAX,
842            (
843                // 2nd level simple fields
844                i64::MAX,
845                true,
846                i64::MAX,
847                // 2nd level array field
848                &["Hello", "World"][..],
849            ),
850            // one more top-most simple field
851            "hello",
852        )];
853        let ctxt = Context::new_dbus(LE, 0);
854        let encoded = to_bytes(ctxt, &ar).unwrap();
855        assert_eq!(encoded.len(), 78);
856        #[allow(clippy::type_complexity)]
857        let decoded: Vec<(u8, u32, (i64, bool, i64, Vec<&str>), &str)> =
858            encoded.deserialize().unwrap().0;
859        assert_eq!(decoded.len(), 1);
860        let r = &decoded[0];
861        assert_eq!(r.0, u8::MAX);
862        assert_eq!(r.1, u32::MAX);
863        let inner_r = &r.2;
864        assert_eq!(inner_r.0, i64::MAX);
865        assert!(inner_r.1);
866        assert_eq!(inner_r.2, i64::MAX);
867        let as_ = &inner_r.3;
868        assert_eq!(as_.len(), 2);
869        assert_eq!(as_[0], "Hello");
870        assert_eq!(as_[1], "World");
871        assert_eq!(r.3, "hello");
872
873        // GVariant format now
874        #[cfg(feature = "gvariant")]
875        {
876            let ctxt = Context::new_gvariant(LE, 0);
877            let gv_encoded = to_bytes(ctxt, &ar).unwrap();
878            assert_eq!(gv_encoded.len(), 54);
879            let decoded: Vec<(u8, u32, (i64, bool, i64, Vec<&str>), &str)> =
880                gv_encoded.deserialize().unwrap().0;
881            assert_eq!(decoded.len(), 1);
882            let r = &decoded[0];
883            assert_eq!(r.0, u8::MAX);
884            assert_eq!(r.1, u32::MAX);
885            let inner_r = &r.2;
886            assert_eq!(inner_r.0, i64::MAX);
887            assert!(inner_r.1);
888            assert_eq!(inner_r.2, i64::MAX);
889            let as_ = &inner_r.3;
890            assert_eq!(as_.len(), 2);
891            assert_eq!(as_[0], "Hello");
892            assert_eq!(as_[1], "World");
893            assert_eq!(r.3, "hello");
894
895            // Check encoding against GLib
896            let bytes = Bytes::from_owned(gv_encoded);
897            let variant = Variant::from_bytes::<
898                Vec<(u8, u32, (i64, bool, i64, Vec<String>), String)>,
899            >(&bytes);
900            assert_eq!(variant.n_children(), 1);
901            let r: (u8, u32, (i64, bool, i64, Vec<String>), String) =
902                variant.child_value(0).get().unwrap();
903            assert_eq!(r.0, u8::MAX);
904            assert_eq!(r.1, u32::MAX);
905        }
906        let ctxt = Context::new_dbus(LE, 0);
907
908        // As Value
909        let v: Value<'_> = ar[..].into();
910        assert_eq!(v.value_signature(), "a(yu(xbxas)s)");
911        let encoded = to_bytes(ctxt, &v).unwrap();
912        assert_eq!(encoded.len(), 94);
913        let v = encoded.deserialize::<Value<'_>>().unwrap().0;
914        if let Value::Array(array) = v.try_clone().unwrap() {
915            assert_eq!(*array.element_signature(), "(yu(xbxas)s)");
916            assert_eq!(array.len(), 1);
917            let r = &array[0];
918            if let Value::Structure(r) = r {
919                let fields = r.fields();
920                assert_eq!(fields[0], Value::U8(u8::MAX));
921                assert_eq!(fields[1], Value::U32(u32::MAX));
922                if let Value::Structure(r) = &fields[2] {
923                    let fields = r.fields();
924                    assert_eq!(fields[0], Value::I64(i64::MAX));
925                    assert_eq!(fields[1], Value::Bool(true));
926                    assert_eq!(fields[2], Value::I64(i64::MAX));
927                    if let Value::Array(as_) = &fields[3] {
928                        assert_eq!(as_.len(), 2);
929                        assert_eq!(as_[0], Value::new("Hello"));
930                        assert_eq!(as_[1], Value::new("World"));
931                    } else {
932                        panic!();
933                    }
934                } else {
935                    panic!();
936                }
937                assert_eq!(fields[3], Value::new("hello"));
938            } else {
939                panic!();
940            }
941        } else {
942            panic!();
943        }
944
945        // GVariant format now
946        #[cfg(feature = "gvariant")]
947        {
948            use rand::{distributions::Alphanumeric, thread_rng, Rng};
949
950            let ctxt = Context::new_gvariant(LE, 0);
951            let gv_encoded = to_bytes(ctxt, &v).unwrap();
952            assert_eq!(gv_encoded.len(), 68);
953            let v: Value<'_> = gv_encoded.deserialize().unwrap().0;
954            if let Value::Array(array) = v {
955                assert_eq!(*array.element_signature(), "(yu(xbxas)s)");
956                assert_eq!(array.len(), 1);
957                let r = &array.get(0).unwrap().unwrap();
958                if let Value::Structure(r) = r {
959                    let fields = r.fields();
960                    assert_eq!(fields[0], Value::U8(u8::MAX));
961                    assert_eq!(fields[1], Value::U32(u32::MAX));
962                    if let Value::Structure(r) = &fields[2] {
963                        let fields = r.fields();
964                        assert_eq!(fields[0], Value::I64(i64::MAX));
965                        assert_eq!(fields[1], Value::Bool(true));
966                        assert_eq!(fields[2], Value::I64(i64::MAX));
967                        if let Value::Array(as_) = &fields[3] {
968                            assert_eq!(as_.len(), 2);
969                            assert_eq!(as_.get(0).unwrap(), Some("Hello"));
970                            assert_eq!(as_.get(1).unwrap(), Some("World"));
971                        } else {
972                            panic!();
973                        }
974                    } else {
975                        panic!();
976                    }
977                    assert_eq!(fields[3], Value::new("hello"));
978                } else {
979                    panic!();
980                }
981            } else {
982                panic!();
983            }
984
985            // Check encoding against GLib
986            let bytes = Bytes::from_owned(gv_encoded);
987            let variant = Variant::from_bytes::<Variant>(&bytes);
988            assert_eq!(variant.n_children(), 1);
989            let child: Variant = variant.child_value(0);
990            let r: (u8, u32, (i64, bool, i64, Vec<String>), String) =
991                child.child_value(0).get().unwrap();
992            assert_eq!(r.0, u8::MAX);
993            assert_eq!(r.1, u32::MAX);
994
995            let mut rng = thread_rng();
996            // Let's test GVariant ser/de of a 254 byte array with variable-width elements as to
997            // ensure no problems with non-normal BS of GVariant.
998            let as_ = vec![
999                (&mut rng)
1000                    .sample_iter(Alphanumeric)
1001                    .map(char::from)
1002                    .take(126)
1003                    .collect::<String>(),
1004                (&mut rng)
1005                    .sample_iter(Alphanumeric)
1006                    .map(char::from)
1007                    .take(126)
1008                    .collect::<String>(),
1009            ];
1010            let gv_encoded = to_bytes(ctxt, &as_).unwrap();
1011            // 252 chars + 2 null terminator bytes doesn't leave room for 2 framing offset bytes so
1012            // a 2-byte offset is chosen by the serializer.
1013            assert_eq!(gv_encoded.len(), 258);
1014
1015            // Check encoding against GLib
1016            let bytes = Bytes::from_owned(gv_encoded.to_owned());
1017            let variant = Variant::from_bytes::<Vec<String>>(&bytes);
1018            assert_eq!(variant.n_children(), 2);
1019            assert_eq!(variant.child_value(0).get::<String>().unwrap(), as_[0]);
1020            assert_eq!(variant.child_value(1).get::<String>().unwrap(), as_[1]);
1021            // Also check if our own deserializer does the right thing
1022            let as2: Vec<String> = gv_encoded.deserialize().unwrap().0;
1023            assert_eq!(as2, as_);
1024
1025            // Test conversion of Array of Value to Vec<Value>
1026            let v = Value::new(vec![Value::new(43), Value::new("bonjour")]);
1027            let av = <Array<'_>>::try_from(v).unwrap();
1028            let av = <Vec<Value<'_>>>::try_from(av).unwrap();
1029            assert_eq!(av[0], Value::new(43));
1030            assert_eq!(av[1], Value::new("bonjour"));
1031
1032            let vec = vec![1, 2];
1033            let val = Value::new(&vec);
1034            assert_eq!(TryInto::<Vec<i32>>::try_into(val).unwrap(), vec);
1035        }
1036    }
1037
1038    #[test]
1039    fn struct_byte_array() {
1040        let ctxt = Context::new_dbus(LE, 0);
1041        let value: (Vec<u8>, HashMap<String, Value<'_>>) = (Vec::new(), HashMap::new());
1042        let value = zvariant::to_bytes(ctxt, &value).unwrap();
1043        #[cfg(feature = "serde_bytes")]
1044        let (bytes, map): (&serde_bytes::Bytes, HashMap<&str, Value<'_>>) = value
1045            .deserialize()
1046            .expect("Could not deserialize serde_bytes::Bytes in struct.")
1047            .0;
1048        #[cfg(not(feature = "serde_bytes"))]
1049        let (bytes, map): (&[u8], HashMap<&str, Value<'_>>) = value
1050            .deserialize()
1051            .expect("Could not deserialize u8 slice in struct")
1052            .0;
1053
1054        assert!(bytes.is_empty());
1055        assert!(map.is_empty());
1056    }
1057
1058    #[test]
1059    fn struct_value() {
1060        // Struct->Value
1061        let s: Value<'_> = ("a", "b", (1, 2)).into();
1062
1063        let ctxt = Context::new_dbus(LE, 0);
1064        let encoded = to_bytes(ctxt, &s).unwrap();
1065        assert_eq!(dbg!(encoded.len()), 40);
1066        let decoded: Value<'_> = encoded.deserialize().unwrap().0;
1067        let s = <Structure<'_>>::try_from(decoded).unwrap();
1068        let outer = <(Str<'_>, Str<'_>, Structure<'_>)>::try_from(s).unwrap();
1069        assert_eq!(outer.0, "a");
1070        assert_eq!(outer.1, "b");
1071
1072        let inner = <(i32, i32)>::try_from(outer.2).unwrap();
1073        assert_eq!(inner.0, 1);
1074        assert_eq!(inner.1, 2);
1075
1076        #[derive(Serialize, Deserialize, Type, PartialEq, Debug)]
1077        struct Foo {
1078            val: u32,
1079        }
1080
1081        let foo = Foo { val: 99 };
1082        let v = SerializeValue(&foo);
1083        let encoded = to_bytes(ctxt, &v).unwrap();
1084        let decoded: DeserializeValue<'_, Foo> = encoded.deserialize().unwrap().0;
1085        assert_eq!(decoded.0, foo);
1086
1087        // Unit struct should be treated as a 0-sized tuple (the same as unit type)
1088        #[derive(Serialize, Deserialize, Type, PartialEq, Debug)]
1089        struct Unit;
1090
1091        assert_eq!(Unit::signature(), "");
1092        let encoded = to_bytes(ctxt, &Unit).unwrap();
1093        assert_eq!(encoded.len(), 0);
1094        let _decoded: Unit = encoded.deserialize().unwrap().0;
1095
1096        // Structs w/o fields should be treated as a unit struct.
1097        #[derive(Serialize, Deserialize, Type, PartialEq, Debug)]
1098        struct NoFields {}
1099
1100        assert_eq!(NoFields::signature(), "y");
1101        let encoded = to_bytes(ctxt, &NoFields {}).unwrap();
1102        assert_eq!(encoded.len(), 1);
1103        let _decoded: NoFields = encoded.deserialize().unwrap().0;
1104
1105        #[cfg(feature = "gvariant")]
1106        {
1107            let ctxt = Context::new_gvariant(LE, 0);
1108            let encoded = to_bytes(ctxt, &NoFields {}).unwrap();
1109            assert_eq!(encoded.len(), 1);
1110            let _decoded: NoFields = encoded.deserialize().unwrap().0;
1111        }
1112    }
1113
1114    #[test]
1115    fn struct_ref() {
1116        let ctxt = Context::new_dbus(LE, 0);
1117        let encoded = to_bytes(ctxt, &(&1u32, &2u32)).unwrap();
1118        let decoded: [u32; 2] = encoded.deserialize().unwrap().0;
1119        assert_eq!(decoded, [1u32, 2u32]);
1120    }
1121
1122    #[test]
1123    fn dict_value() {
1124        let mut map: HashMap<i64, &str> = HashMap::new();
1125        map.insert(1, "123");
1126        map.insert(2, "456");
1127        let ctxt = Context::new_dbus(LE, 0);
1128        let encoded = to_bytes(ctxt, &map).unwrap();
1129        assert_eq!(dbg!(encoded.len()), 40);
1130        let decoded: HashMap<i64, &str> = encoded.deserialize().unwrap().0;
1131        assert_eq!(decoded[&1], "123");
1132        assert_eq!(decoded[&2], "456");
1133
1134        // GVariant format now
1135        #[cfg(feature = "gvariant")]
1136        {
1137            let ctxt = Context::new_gvariant(NATIVE_ENDIAN, 0);
1138            let gv_encoded = to_bytes(ctxt, &map).unwrap();
1139            assert_eq!(gv_encoded.len(), 30);
1140            let map: HashMap<i64, &str> = encoded.deserialize().unwrap().0;
1141            assert_eq!(map[&1], "123");
1142            assert_eq!(map[&2], "456");
1143
1144            // Check encoding against GLib
1145            let bytes = Bytes::from_owned(gv_encoded);
1146            let variant = Variant::from_bytes::<HashMap<i64, &str>>(&bytes);
1147            assert_eq!(variant.n_children(), 2);
1148            let map: HashMap<i64, String> = HashMap::from_variant(&variant).unwrap();
1149            assert_eq!(map[&1], "123");
1150            assert_eq!(map[&2], "456");
1151        }
1152        let ctxt = Context::new_dbus(LE, 0);
1153
1154        // As Value
1155        let v: Value<'_> = Dict::from(map).into();
1156        assert_eq!(v.value_signature(), "a{xs}");
1157        let encoded = to_bytes(ctxt, &v).unwrap();
1158        assert_eq!(encoded.len(), 48);
1159        // Convert it back
1160        let dict: Dict<'_, '_> = v.try_into().unwrap();
1161        let map: HashMap<i64, String> = dict.try_clone().unwrap().try_into().unwrap();
1162        assert_eq!(map[&1], "123");
1163        assert_eq!(map[&2], "456");
1164        // Also decode it back
1165        let v = encoded.deserialize().unwrap().0;
1166        if let Value::Dict(dict) = v {
1167            assert_eq!(dict.get::<i64, &str>(&1).unwrap().unwrap(), "123");
1168            assert_eq!(dict.get::<i64, &str>(&2).unwrap().unwrap(), "456");
1169        } else {
1170            panic!();
1171        }
1172        // Convert it to a BTreeMap too.
1173        let map: BTreeMap<i64, String> = dict.try_into().unwrap();
1174        assert_eq!(map[&1], "123");
1175        assert_eq!(map[&2], "456");
1176        // Use iterator
1177        let mut dict = Dict::from(map);
1178        let expect = vec![
1179            (Value::from(1i64), Value::from("123")),
1180            (Value::from(2i64), Value::from("456")),
1181        ];
1182        let expect_iter = expect.iter().map(|(k, v)| (k, v)).collect::<Vec<_>>();
1183        let actual = dict.iter().collect::<Vec<_>>();
1184        assert_eq!(actual, expect_iter);
1185        let actual = dict.iter().collect::<Vec<_>>();
1186        assert_eq!(actual, expect_iter);
1187        let actual = dict.iter().collect::<Vec<_>>();
1188        assert_eq!(actual, expect_iter);
1189        for (_, v) in dict.iter_mut() {
1190            if let Value::Str(vv) = v {
1191                *vv = Str::from(vv.to_string() + "-hello");
1192            }
1193        }
1194        let actual = dict.into_iter().collect::<Vec<_>>();
1195        let expect = vec![
1196            (Value::from(1i64), Value::from("123-hello")),
1197            (Value::from(2i64), Value::from("456-hello")),
1198        ];
1199        assert_eq!(actual, expect);
1200
1201        #[cfg(feature = "gvariant")]
1202        {
1203            // GVariant-format requires framing offsets for dict entries with variable-length keys
1204            // so let's test that.
1205            let mut map: HashMap<&str, &str> = HashMap::new();
1206            map.insert("hi", "1234");
1207            map.insert("world", "561");
1208            let ctxt = Context::new_gvariant(NATIVE_ENDIAN, 0);
1209            let gv_encoded = to_bytes(ctxt, &map).unwrap();
1210            assert_eq!(gv_encoded.len(), 22);
1211            let map: HashMap<&str, &str> = gv_encoded.deserialize().unwrap().0;
1212            assert_eq!(map["hi"], "1234");
1213            assert_eq!(map["world"], "561");
1214
1215            // Ensure SerializeValue produces the same result as Value
1216            // Tests for https://github.com/dbus2/zbus/issues/868
1217            let mut map = std::collections::HashMap::<&str, &str>::new();
1218            map.insert("k", "v");
1219            let gv_ser_value_encoded =
1220                zvariant::to_bytes(ctxt, &zvariant::SerializeValue(&map)).unwrap();
1221            let gv_value_encoded = to_bytes(ctxt, &zvariant::Value::new(map)).unwrap();
1222            assert_eq!(gv_value_encoded.as_ref(), gv_ser_value_encoded.as_ref());
1223
1224            // Check encoding against GLib
1225            let bytes = Bytes::from_owned(gv_encoded);
1226            let variant = Variant::from_bytes::<HashMap<&str, &str>>(&bytes);
1227            assert_eq!(variant.n_children(), 2);
1228            let map: HashMap<String, String> = HashMap::from_variant(&variant).unwrap();
1229            assert_eq!(map["hi"], "1234");
1230            assert_eq!(map["world"], "561");
1231
1232            // Now the same but empty dict this time
1233            let map: HashMap<&str, &str> = HashMap::new();
1234            let gv_encoded = to_bytes(ctxt, &map).unwrap();
1235            assert_eq!(gv_encoded.len(), 0);
1236            let map: HashMap<&str, &str> = gv_encoded.deserialize().unwrap().0;
1237            assert_eq!(map.len(), 0);
1238        }
1239        let ctxt = Context::new_dbus(LE, 0);
1240
1241        // Now a hand-crafted Dict Value but with a Value as value
1242        let mut dict = Dict::new(<&str>::signature(), Value::signature());
1243        dict.add("hello", Value::new("there")).unwrap();
1244        dict.add("bye", Value::new("now")).unwrap();
1245        let v: Value<'_> = dict.into();
1246        assert_eq!(v.value_signature(), "a{sv}");
1247        let encoded = to_bytes(ctxt, &v).unwrap();
1248        assert_eq!(dbg!(encoded.len()), 66);
1249        let v: Value<'_> = encoded.deserialize().unwrap().0;
1250        if let Value::Dict(dict) = v {
1251            assert_eq!(
1252                dict.get::<&str, Value<'_>>(&"hello").unwrap().unwrap(),
1253                Value::new("there")
1254            );
1255            assert_eq!(
1256                dict.get::<_, Value<'_>>(&"bye").unwrap().unwrap(),
1257                Value::new("now")
1258            );
1259
1260            // Try converting to a HashMap
1261            let map = <HashMap<String, Value<'_>>>::try_from(dict.try_clone().unwrap()).unwrap();
1262            assert_eq!(map["hello"], Value::new("there"));
1263            assert_eq!(map["bye"], Value::new("now"));
1264
1265            // Try converting to a BTreeMap
1266            let map = <BTreeMap<String, Value<'_>>>::try_from(dict).unwrap();
1267            assert_eq!(map["hello"], Value::new("there"));
1268            assert_eq!(map["bye"], Value::new("now"));
1269        } else {
1270            panic!();
1271        }
1272
1273        #[derive(SerializeDict, DeserializeDict, Type, PartialEq, Debug)]
1274        #[zvariant(signature = "a{sv}")]
1275        struct Test {
1276            process_id: Option<u32>,
1277            group_id: Option<u32>,
1278            user: String,
1279        }
1280        let test = Test {
1281            process_id: Some(42),
1282            group_id: None,
1283            user: "me".to_string(),
1284        };
1285
1286        let encoded = to_bytes(ctxt, &test).unwrap();
1287        assert_eq!(encoded.len(), 51);
1288
1289        let decoded: HashMap<&str, Value<'_>> = encoded.deserialize().unwrap().0;
1290        assert_eq!(decoded["process_id"], Value::U32(42));
1291        assert_eq!(decoded["user"], Value::new("me"));
1292        assert!(!decoded.contains_key("group_id"));
1293
1294        let decoded: Test = encoded.deserialize().unwrap().0;
1295        assert_eq!(decoded, test);
1296
1297        #[derive(SerializeDict, DeserializeDict, Type, PartialEq, Debug)]
1298        #[zvariant(signature = "a{sv}")]
1299        struct TestMissing {
1300            process_id: Option<u32>,
1301            group_id: Option<u32>,
1302            user: String,
1303            quota: u8,
1304        }
1305        let decoded: Result<(TestMissing, _)> = encoded.deserialize();
1306        assert_eq!(
1307            decoded.unwrap_err(),
1308            Error::Message("missing field `quota`".to_string())
1309        );
1310
1311        #[derive(SerializeDict, DeserializeDict, Type, PartialEq, Debug)]
1312        #[zvariant(signature = "a{sv}")]
1313        struct TestSkipUnknown {
1314            process_id: Option<u32>,
1315            group_id: Option<u32>,
1316        }
1317        let _: TestSkipUnknown = encoded.deserialize().unwrap().0;
1318
1319        #[derive(SerializeDict, DeserializeDict, Type, PartialEq, Debug)]
1320        #[zvariant(deny_unknown_fields, signature = "a{sv}")]
1321        struct TestUnknown {
1322            process_id: Option<u32>,
1323            group_id: Option<u32>,
1324        }
1325        let decoded: Result<(TestUnknown, _)> = encoded.deserialize();
1326        assert_eq!(
1327            decoded.unwrap_err(),
1328            Error::Message("unknown field `user`, expected `process_id` or `group_id`".to_string())
1329        );
1330    }
1331
1332    #[test]
1333    fn dict_compare() {
1334        // the order in which a dict has been constructed must not play a role
1335        // https://github.com/dbus2/zbus/issues/484
1336        let mut dict1 = Dict::new(<&str>::signature(), Value::signature());
1337        dict1.add("first", Value::new("value")).unwrap();
1338        dict1.add("second", Value::new("value")).unwrap();
1339
1340        let mut dict2 = Dict::new(<&str>::signature(), Value::signature());
1341        dict2.add("second", Value::new("value")).unwrap();
1342        dict2.add("first", Value::new("value")).unwrap();
1343
1344        assert_eq!(dict1, dict2);
1345    }
1346
1347    #[test]
1348    fn value_value() {
1349        let ctxt = Context::new_dbus(BE, 0);
1350        let encoded = to_bytes(ctxt, &0xABBA_ABBA_ABBA_ABBA_u64).unwrap();
1351        assert_eq!(encoded.len(), 8);
1352        assert_eq!(LE.read_u64(&encoded), 0xBAAB_BAAB_BAAB_BAAB_u64);
1353        let decoded: u64 = encoded.deserialize().unwrap().0;
1354        assert_eq!(decoded, 0xABBA_ABBA_ABBA_ABBA);
1355
1356        // Lie about there being bytes before
1357        let ctxt = Context::new_dbus(LE, 2);
1358        let encoded = to_bytes(ctxt, &0xABBA_ABBA_ABBA_ABBA_u64).unwrap();
1359        assert_eq!(encoded.len(), 14);
1360        let decoded: u64 = encoded.deserialize().unwrap().0;
1361        assert_eq!(decoded, 0xABBA_ABBA_ABBA_ABBA_u64);
1362        let ctxt = Context::new_dbus(LE, 0);
1363
1364        // As Value
1365        let v: Value<'_> = 0xFEFE_u64.into();
1366        assert_eq!(v.value_signature(), "t");
1367        let encoded = to_bytes(ctxt, &v).unwrap();
1368        assert_eq!(encoded.len(), 16);
1369        let v = encoded.deserialize().unwrap().0;
1370        assert_eq!(v, Value::U64(0xFEFE));
1371
1372        // And now as Value in a Value
1373        let v = Value::Value(Box::new(v));
1374        let encoded = to_bytes(ctxt, &v).unwrap();
1375        assert_eq!(encoded.len(), 16);
1376        let v = encoded.deserialize().unwrap().0;
1377        if let Value::Value(v) = v {
1378            assert_eq!(v.value_signature(), "t");
1379            assert_eq!(*v, Value::U64(0xFEFE));
1380        } else {
1381            panic!();
1382        }
1383
1384        // Ensure Value works with other Serializer & Deserializer
1385        let v: Value<'_> = 0xFEFE_u64.into();
1386        let encoded = serde_json::to_string(&v).unwrap();
1387        let v = serde_json::from_str::<Value<'_>>(&encoded).unwrap();
1388        assert_eq!(v, Value::U64(0xFEFE));
1389    }
1390
1391    #[test]
1392    fn enums() {
1393        use serde::{Deserialize, Serialize};
1394
1395        #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
1396        enum Unit {
1397            Variant1,
1398            Variant2,
1399            Variant3,
1400        }
1401
1402        let ctxts_n_expected_lens = [
1403            // Unit variants are encoded as u32 and that has the same encoding in both formats.
1404            [
1405                (Context::new_dbus(BE, 0), 4usize),
1406                (Context::new_dbus(BE, 1), 7),
1407                (Context::new_dbus(BE, 2), 6),
1408                (Context::new_dbus(BE, 3), 5),
1409                (Context::new_dbus(BE, 4), 4),
1410            ],
1411            #[cfg(feature = "gvariant")]
1412            [
1413                (Context::new_gvariant(BE, 0), 4usize),
1414                (Context::new_gvariant(BE, 1), 7),
1415                (Context::new_gvariant(BE, 2), 6),
1416                (Context::new_gvariant(BE, 3), 5),
1417                (Context::new_gvariant(BE, 4), 4),
1418            ],
1419        ];
1420        for ctxts_n_expected_len in ctxts_n_expected_lens {
1421            for (ctxt, expected_len) in ctxts_n_expected_len {
1422                let encoded = to_bytes_for_signature(ctxt, "u", &Unit::Variant2).unwrap();
1423                assert_eq!(encoded.len(), expected_len);
1424                let decoded: Unit = encoded.deserialize_for_signature("u").unwrap().0;
1425                assert_eq!(decoded, Unit::Variant2);
1426            }
1427        }
1428
1429        #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
1430        enum NewType<'s> {
1431            Variant1(&'s str),
1432            Variant2(&'s str),
1433            Variant3(&'s str),
1434        }
1435
1436        let ctxts_n_expected_lens = [
1437            [
1438                (Context::new_dbus(BE, 0), 14usize),
1439                (Context::new_dbus(BE, 1), 21),
1440                (Context::new_dbus(BE, 2), 20),
1441                (Context::new_dbus(BE, 3), 19),
1442                (Context::new_dbus(BE, 4), 18),
1443            ],
1444            #[cfg(feature = "gvariant")]
1445            [
1446                (Context::new_gvariant(BE, 0), 10usize),
1447                (Context::new_gvariant(BE, 1), 13),
1448                (Context::new_gvariant(BE, 2), 12),
1449                (Context::new_gvariant(BE, 3), 11),
1450                (Context::new_gvariant(BE, 4), 10),
1451            ],
1452        ];
1453        for ctxts_n_expected_len in ctxts_n_expected_lens {
1454            for (ctxt, expected_len) in ctxts_n_expected_len {
1455                let encoded =
1456                    to_bytes_for_signature(ctxt, "(us)", &NewType::Variant2("hello")).unwrap();
1457                assert_eq!(encoded.len(), expected_len);
1458                let decoded: NewType<'_> = encoded.deserialize_for_signature("(us)").unwrap().0;
1459                assert_eq!(decoded, NewType::Variant2("hello"));
1460            }
1461        }
1462
1463        #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
1464        enum Structs {
1465            Tuple(u8, u32),
1466            Struct { y: u8, t: u32 },
1467        }
1468
1469        let ctxts_n_expected_lens = [
1470            [
1471                (Context::new_dbus(BE, 0), 16usize),
1472                (Context::new_dbus(BE, 1), 23),
1473                (Context::new_dbus(BE, 2), 22),
1474                (Context::new_dbus(BE, 3), 21),
1475                (Context::new_dbus(BE, 4), 20),
1476            ],
1477            #[cfg(feature = "gvariant")]
1478            [
1479                (Context::new_gvariant(BE, 0), 12usize),
1480                (Context::new_gvariant(BE, 1), 15),
1481                (Context::new_gvariant(BE, 2), 14),
1482                (Context::new_gvariant(BE, 3), 13),
1483                (Context::new_gvariant(BE, 4), 12),
1484            ],
1485        ];
1486        // TODO: Provide convenience API to create complex signatures
1487        let signature = "(u(yu))";
1488        for ctxts_n_expected_len in ctxts_n_expected_lens {
1489            for (ctxt, expected_len) in ctxts_n_expected_len {
1490                let encoded =
1491                    to_bytes_for_signature(ctxt, signature, &Structs::Tuple(42, 42)).unwrap();
1492                assert_eq!(encoded.len(), expected_len);
1493                let decoded: Structs = encoded.deserialize_for_signature(signature).unwrap().0;
1494                assert_eq!(decoded, Structs::Tuple(42, 42));
1495
1496                let s = Structs::Struct { y: 42, t: 42 };
1497                let encoded = to_bytes_for_signature(ctxt, signature, &s).unwrap();
1498                assert_eq!(encoded.len(), expected_len);
1499                let decoded: Structs = encoded.deserialize_for_signature(signature).unwrap().0;
1500                assert_eq!(decoded, Structs::Struct { y: 42, t: 42 });
1501            }
1502        }
1503    }
1504
1505    #[test]
1506    fn derive() {
1507        use serde::{Deserialize, Serialize};
1508        use serde_repr::{Deserialize_repr, Serialize_repr};
1509
1510        #[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
1511        struct Struct<'s> {
1512            field1: u16,
1513            field2: i64,
1514            field3: &'s str,
1515        }
1516
1517        assert_eq!(Struct::signature(), "(qxs)");
1518        let s = Struct {
1519            field1: 0xFF_FF,
1520            field2: 0xFF_FF_FF_FF_FF_FF,
1521            field3: "hello",
1522        };
1523        let ctxt = Context::new_dbus(LE, 0);
1524        let encoded = to_bytes(ctxt, &s).unwrap();
1525        assert_eq!(encoded.len(), 26);
1526        let decoded: Struct<'_> = encoded.deserialize().unwrap().0;
1527        assert_eq!(decoded, s);
1528
1529        #[derive(Deserialize, Serialize, Type)]
1530        struct UnitStruct;
1531
1532        assert_eq!(UnitStruct::signature(), <()>::signature());
1533        let encoded = to_bytes(ctxt, &UnitStruct).unwrap();
1534        assert_eq!(encoded.len(), 0);
1535        let _: UnitStruct = encoded.deserialize().unwrap().0;
1536
1537        #[repr(u8)]
1538        #[derive(Deserialize_repr, Serialize_repr, Type, Debug, PartialEq)]
1539        enum Enum {
1540            Variant1,
1541            Variant2,
1542            Variant3,
1543        }
1544
1545        assert_eq!(Enum::signature(), u8::signature());
1546        let encoded = to_bytes(ctxt, &Enum::Variant3).unwrap();
1547        assert_eq!(encoded.len(), 1);
1548        let decoded: Enum = encoded.deserialize().unwrap().0;
1549        assert_eq!(decoded, Enum::Variant3);
1550
1551        #[repr(i64)]
1552        #[derive(Deserialize_repr, Serialize_repr, Type, Debug, PartialEq)]
1553        enum Enum2 {
1554            Variant1,
1555            Variant2,
1556            Variant3,
1557        }
1558
1559        assert_eq!(Enum2::signature(), i64::signature());
1560        let encoded = to_bytes(ctxt, &Enum2::Variant2).unwrap();
1561        assert_eq!(encoded.len(), 8);
1562        let decoded: Enum2 = encoded.deserialize().unwrap().0;
1563        assert_eq!(decoded, Enum2::Variant2);
1564
1565        #[derive(Deserialize, Serialize, Type, Debug, PartialEq)]
1566        enum NoReprEnum {
1567            Variant1,
1568            Variant2,
1569            Variant3,
1570        }
1571
1572        // issue#265: Panic on deserialization of a structure w/ a unit enum as its last field.
1573        let encoded = to_bytes(ctxt, &(NoReprEnum::Variant2,)).unwrap();
1574        let _: (NoReprEnum,) = encoded.deserialize().unwrap().0;
1575
1576        assert_eq!(NoReprEnum::signature(), u32::signature());
1577        let encoded = to_bytes(ctxt, &NoReprEnum::Variant2).unwrap();
1578        assert_eq!(encoded.len(), 4);
1579        let decoded: NoReprEnum = encoded.deserialize().unwrap().0;
1580        assert_eq!(decoded, NoReprEnum::Variant2);
1581
1582        #[derive(Deserialize, Serialize, Type, Debug, PartialEq)]
1583        #[zvariant(signature = "s")]
1584        enum StrEnum {
1585            Variant1,
1586            Variant2,
1587            Variant3,
1588        }
1589
1590        assert_eq!(StrEnum::signature(), <&str>::signature());
1591        let encoded = to_bytes(ctxt, &StrEnum::Variant2).unwrap();
1592        assert_eq!(encoded.len(), 13);
1593        let decoded: StrEnum = encoded.deserialize().unwrap().0;
1594        assert_eq!(decoded, StrEnum::Variant2);
1595
1596        #[derive(Deserialize, Serialize, Type)]
1597        enum NewType {
1598            Variant1(f64),
1599            Variant2(f64),
1600        }
1601        assert_eq!(NewType::signature(), "(ud)");
1602
1603        #[derive(Deserialize, Serialize, Type)]
1604        enum StructFields {
1605            Variant1(u16, i64, &'static str),
1606            Variant2 {
1607                field1: u16,
1608                field2: i64,
1609                field3: &'static str,
1610            },
1611        }
1612        assert_eq!(StructFields::signature(), "(u(qxs))");
1613
1614        #[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
1615        struct AStruct<'s> {
1616            field1: u16,
1617            field2: &'s [u8],
1618            field3: &'s [u8],
1619            field4: i64,
1620        }
1621        assert_eq!(AStruct::signature(), "(qayayx)");
1622        let s = AStruct {
1623            field1: 0xFF_FF,
1624            field2: &[77u8; 8],
1625            field3: &[77u8; 8],
1626            field4: 0xFF_FF_FF_FF_FF_FF,
1627        };
1628        let encoded = to_bytes(ctxt, &s).unwrap();
1629        assert_eq!(encoded.len(), 40);
1630        let decoded: AStruct<'_> = encoded.deserialize().unwrap().0;
1631        assert_eq!(decoded, s);
1632    }
1633
1634    #[test]
1635    fn serialized_size() {
1636        let ctxt = Context::new_dbus(LE, 0);
1637        let l = crate::serialized_size(ctxt, &()).unwrap();
1638        assert_eq!(*l, 0);
1639
1640        #[cfg(unix)]
1641        {
1642            let stdout = std::io::stdout();
1643            let l = crate::serialized_size(ctxt, &Fd::from(&stdout)).unwrap();
1644            assert_eq!(*l, 4);
1645            assert_eq!(l.num_fds(), 1);
1646        }
1647
1648        let l = crate::serialized_size(ctxt, &('a', "abc", &(1_u32, 2))).unwrap();
1649        assert_eq!(*l, 24);
1650
1651        let v = vec![1, 2];
1652        let l = crate::serialized_size(ctxt, &('a', "abc", &v)).unwrap();
1653        assert_eq!(*l, 28);
1654    }
1655
1656    #[test]
1657    #[cfg(feature = "serde_bytes")]
1658    fn serde_bytes() {
1659        use serde::{Deserialize, Serialize};
1660        use serde_bytes::*;
1661
1662        let ctxt = Context::new_dbus(LE, 0);
1663        let ay = Bytes::new(&[77u8; 1_000_000]);
1664        let encoded = to_bytes(ctxt, &ay).unwrap();
1665        assert_eq!(encoded.len(), 1_000_004);
1666        let decoded: ByteBuf = encoded.deserialize().unwrap().0;
1667        assert_eq!(decoded.len(), 1_000_000);
1668
1669        #[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
1670        struct Struct<'s> {
1671            field1: u16,
1672            #[serde(with = "serde_bytes")]
1673            field2: &'s [u8],
1674            field3: i64,
1675        }
1676        assert_eq!(Struct::signature(), "(qayx)");
1677        let s = Struct {
1678            field1: 0xFF_FF,
1679            field2: &[77u8; 512],
1680            field3: 0xFF_FF_FF_FF_FF_FF,
1681        };
1682        let encoded = to_bytes(ctxt, &s).unwrap();
1683        assert_eq!(encoded.len(), 528);
1684        let decoded: Struct<'_> = encoded.deserialize().unwrap().0;
1685        assert_eq!(decoded, s);
1686    }
1687
1688    #[test]
1689    #[cfg(all(feature = "serde_bytes", feature = "gvariant"))]
1690    fn serde_bytes_gvariant() {
1691        use serde::{Deserialize, Serialize};
1692        use serde_bytes::*;
1693
1694        let ctxt = Context::new_gvariant(LE, 0);
1695        let ay = Bytes::new(&[77u8; 1_000_000]);
1696        let encoded = to_bytes(ctxt, &ay).unwrap();
1697        assert_eq!(encoded.len(), 1_000_000);
1698        let decoded: ByteBuf = encoded.deserialize().unwrap().0;
1699        assert_eq!(decoded.len(), 1_000_000);
1700
1701        #[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
1702        struct Struct<'s> {
1703            field1: u16,
1704            #[serde(with = "serde_bytes")]
1705            field2: &'s [u8],
1706            field3: i64,
1707        }
1708        assert_eq!(Struct::signature(), "(qayx)");
1709        let s = Struct {
1710            field1: 0xFF_FF,
1711            field2: &[77u8; 512],
1712            field3: 0xFF_FF_FF_FF_FF_FF,
1713        };
1714        let encoded = to_bytes(ctxt, &s).unwrap();
1715        assert_eq!(encoded.len(), 530);
1716        let decoded: Struct<'_> = encoded.deserialize().unwrap().0;
1717        assert_eq!(decoded, s);
1718    }
1719
1720    #[test]
1721    #[cfg(any(feature = "gvariant", feature = "option-as-array"))]
1722    fn option_value() {
1723        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1724        let ctxt = Context::new_gvariant(NATIVE_ENDIAN, 0);
1725        #[cfg(feature = "option-as-array")]
1726        let ctxt = Context::new_dbus(NATIVE_ENDIAN, 0);
1727
1728        // First a Some fixed-sized value
1729        let mn = Some(16i16);
1730        let encoded = to_bytes(ctxt, &mn).unwrap();
1731        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1732        assert_eq!(encoded.len(), 2);
1733        #[cfg(feature = "option-as-array")]
1734        assert_eq!(encoded.len(), 6);
1735        let decoded: Option<i16> = encoded.deserialize().unwrap().0;
1736        assert_eq!(decoded, mn);
1737
1738        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1739        {
1740            // Check encoding against GLib
1741            let bytes = Bytes::from_owned(encoded);
1742            let variant = Variant::from_bytes::<Option<i16>>(&bytes);
1743            assert_eq!(variant.get::<Option<i16>>().unwrap(), mn);
1744        }
1745
1746        // As Value
1747        let v: Value<'_> = mn.into();
1748        let encoded = to_bytes(ctxt, &v).unwrap();
1749        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1750        assert_eq!(encoded.len(), 5);
1751        #[cfg(feature = "option-as-array")]
1752        assert_eq!(encoded.len(), 10);
1753        let decoded: Value<'_> = encoded.deserialize().unwrap().0;
1754        match decoded {
1755            #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1756            Value::Maybe(maybe) => assert_eq!(maybe.get().unwrap(), mn),
1757            #[cfg(feature = "option-as-array")]
1758            Value::Array(array) => {
1759                assert_eq!(i16::try_from(array[0].try_clone().unwrap()).unwrap(), 16i16)
1760            }
1761            _ => panic!("unexpected value {decoded:?}"),
1762        }
1763
1764        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1765        {
1766            // Check encoding against GLib
1767            let bytes = Bytes::from_owned(encoded);
1768            let variant = Variant::from_bytes::<Variant>(&bytes);
1769            let decoded = variant.child_value(0).get::<Option<i16>>().unwrap();
1770            assert_eq!(decoded, mn);
1771        }
1772
1773        // Now a None of the same type
1774        let mn: Option<i16> = None;
1775        let encoded = to_bytes(ctxt, &mn).unwrap();
1776        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1777        assert_eq!(encoded.len(), 0);
1778        #[cfg(feature = "option-as-array")]
1779        assert_eq!(encoded.len(), 4);
1780        let decoded: Option<i16> = encoded.deserialize().unwrap().0;
1781        assert!(decoded.is_none());
1782
1783        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1784        {
1785            // Check encoding against GLib
1786            let bytes = Bytes::from_owned(encoded);
1787            let variant = Variant::from_bytes::<Option<i16>>(&bytes);
1788            assert!(variant.get::<Option<i16>>().unwrap().is_none());
1789        }
1790
1791        // Next a Some variable-sized value
1792        let ms = Some("hello world");
1793        let encoded = to_bytes(ctxt, &ms).unwrap();
1794        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1795        assert_eq!(encoded.len(), 13);
1796        #[cfg(feature = "option-as-array")]
1797        assert_eq!(encoded.len(), 20);
1798        let decoded: Option<&str> = encoded.deserialize().unwrap().0;
1799        assert_eq!(decoded, ms);
1800
1801        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1802        {
1803            // Check encoding against GLib
1804            let bytes = Bytes::from_owned(encoded);
1805            let variant = Variant::from_bytes::<Option<String>>(&bytes);
1806            assert_eq!(
1807                &variant.get::<Option<String>>().unwrap().unwrap(),
1808                ms.unwrap()
1809            );
1810        }
1811
1812        // As Value
1813        let v: Value<'_> = ms.into();
1814        #[cfg(feature = "option-as-array")]
1815        match &v {
1816            Value::Array(array) => {
1817                assert_eq!(
1818                    String::try_from(array[0].try_clone().unwrap()).unwrap(),
1819                    ms.unwrap()
1820                )
1821            }
1822            _ => panic!("unexpected value {v:?}"),
1823        }
1824
1825        let encoded = to_bytes(ctxt, &v).unwrap();
1826        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1827        assert_eq!(encoded.len(), 16);
1828        #[cfg(feature = "option-as-array")]
1829        assert_eq!(encoded.len(), 24);
1830        let decoded: Value<'_> = encoded.deserialize().unwrap().0;
1831        match decoded {
1832            #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1833            Value::Maybe(maybe) => {
1834                assert_eq!(maybe.get::<String>().unwrap().as_deref(), ms);
1835            }
1836            #[cfg(feature = "option-as-array")]
1837            Value::Array(array) => {
1838                assert_eq!(
1839                    String::try_from(array[0].try_clone().unwrap()).unwrap(),
1840                    ms.unwrap()
1841                )
1842            }
1843            _ => panic!("unexpected value {decoded:?}"),
1844        }
1845
1846        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1847        {
1848            // Check encoding against GLib
1849            let bytes = Bytes::from_owned(encoded);
1850            let variant = Variant::from_bytes::<Variant>(&bytes);
1851            let decoded = variant.child_value(0).get::<Option<String>>().unwrap();
1852            assert_eq!(decoded.as_deref(), ms);
1853        }
1854
1855        // Now a None of the same type
1856        let ms: Option<&str> = None;
1857        let encoded = to_bytes(ctxt, &ms).unwrap();
1858        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1859        assert_eq!(encoded.len(), 0);
1860        #[cfg(feature = "option-as-array")]
1861        assert_eq!(encoded.len(), 4);
1862        let decoded: Option<&str> = encoded.deserialize().unwrap().0;
1863        assert!(decoded.is_none());
1864
1865        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1866        {
1867            // Check encoding against GLib
1868            let bytes = Bytes::from_owned(encoded);
1869            let variant = Variant::from_bytes::<Option<String>>(&bytes);
1870            assert!(variant.get::<Option<String>>().unwrap().is_none());
1871        }
1872
1873        // In a seq type
1874        let ams = vec![
1875            Some(String::from("hello world")),
1876            Some(String::from("bye world")),
1877        ];
1878        let encoded = to_bytes(ctxt, &ams).unwrap();
1879        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1880        assert_eq!(encoded.len(), 26);
1881        #[cfg(feature = "option-as-array")]
1882        assert_eq!(encoded.len(), 42);
1883        let decoded: Vec<Option<String>> = encoded.deserialize().unwrap().0;
1884        assert_eq!(decoded, ams);
1885
1886        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1887        {
1888            // Check encoding against GLib
1889            let bytes = Bytes::from_owned(encoded);
1890            let variant = Variant::from_bytes::<Vec<Option<String>>>(&bytes);
1891            let decoded = variant.get::<Vec<Option<String>>>().unwrap();
1892            assert_eq!(decoded, ams);
1893        }
1894
1895        // As Value
1896        let v: Value<'_> = ams.clone().into();
1897        let encoded = to_bytes(ctxt, &v).unwrap();
1898        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1899        assert_eq!(encoded.len(), 30);
1900        #[cfg(feature = "option-as-array")]
1901        assert_eq!(encoded.len(), 50);
1902        let decoded: Value<'_> = encoded.deserialize().unwrap().0;
1903        assert_eq!(v, decoded);
1904
1905        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1906        {
1907            // Check encoding against GLib
1908            let bytes = Bytes::from_owned(encoded);
1909            let variant = Variant::from_bytes::<Variant>(&bytes);
1910            let decoded = variant.child_value(0).get::<Vec<Option<String>>>().unwrap();
1911            assert_eq!(decoded, ams);
1912        }
1913
1914        // In a struct
1915        let structure: (Option<String>, u64, Option<String>) =
1916            (Some(String::from("hello world")), 42u64, None);
1917        let encoded = to_bytes(ctxt, &structure).unwrap();
1918        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1919        assert_eq!(encoded.len(), 25);
1920        #[cfg(feature = "option-as-array")]
1921        assert_eq!(encoded.len(), 36);
1922        let decoded: (Option<String>, u64, Option<String>) = encoded.deserialize().unwrap().0;
1923        assert_eq!(decoded, structure);
1924
1925        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1926        {
1927            // Check encoding against GLib
1928            let bytes = Bytes::from_owned(encoded);
1929            let variant = Variant::from_bytes::<(Option<String>, u64, Option<String>)>(&bytes);
1930            let decoded = variant
1931                .get::<(Option<String>, u64, Option<String>)>()
1932                .unwrap();
1933            assert_eq!(decoded, structure);
1934        }
1935
1936        // As Value
1937        let v: Value<'_> = structure.clone().into();
1938        let encoded = to_bytes(ctxt, &v).unwrap();
1939        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1940        assert_eq!(encoded.len(), 33);
1941        #[cfg(feature = "option-as-array")]
1942        assert_eq!(encoded.len(), 52);
1943        let decoded: Value<'_> = encoded.deserialize().unwrap().0;
1944        assert_eq!(v, decoded);
1945
1946        #[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
1947        {
1948            // Check encoding against GLib
1949            let bytes = Bytes::from_owned(encoded);
1950            let variant = Variant::from_bytes::<Variant>(&bytes);
1951            let decoded = variant
1952                .child_value(0)
1953                .get::<(Option<String>, u64, Option<String>)>()
1954                .unwrap();
1955            assert_eq!(decoded, structure);
1956        }
1957    }
1958
1959    #[test]
1960    fn struct_with_hashmap() {
1961        use serde::{Deserialize, Serialize};
1962
1963        let mut hmap = HashMap::new();
1964        hmap.insert("key".into(), "value".into());
1965
1966        #[derive(Type, Deserialize, Serialize, PartialEq, Debug)]
1967        struct Foo {
1968            hmap: HashMap<String, String>,
1969        }
1970
1971        let foo = Foo { hmap };
1972        assert_eq!(Foo::signature(), "(a{ss})");
1973
1974        let ctxt = Context::new_dbus(LE, 0);
1975        let encoded = to_bytes(ctxt, &(&foo, 1)).unwrap();
1976        let f: Foo = encoded.deserialize().unwrap().0;
1977        assert_eq!(f, foo);
1978    }
1979
1980    #[test]
1981    fn issue_59() {
1982        // Ensure we don't panic on deserializing tuple of smaller than expected length.
1983        let ctxt = Context::new_dbus(LE, 0);
1984        let encoded = to_bytes(ctxt, &("hello",)).unwrap();
1985        let result: Result<((&str, &str), _)> = encoded.deserialize();
1986        assert!(result.is_err());
1987    }
1988
1989    #[test]
1990    #[cfg(feature = "gvariant")]
1991    fn issue_99() {
1992        #[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
1993        struct ZVStruct<'s>(#[serde(borrow)] HashMap<&'s str, Value<'s>>);
1994
1995        let mut dict = HashMap::new();
1996        dict.insert("hi", Value::from("hello"));
1997        dict.insert("bye", Value::from("then"));
1998
1999        let element = ZVStruct(dict);
2000
2001        let ctxt = Context::new_gvariant(LE, 0);
2002        let signature = ZVStruct::signature();
2003
2004        let encoded = to_bytes_for_signature(ctxt, &signature, &element).unwrap();
2005        let _: ZVStruct<'_> = encoded.deserialize_for_signature(signature).unwrap().0;
2006    }
2007
2008    #[test]
2009    fn ip_addr() {
2010        let ctxt = Context::new_dbus(LE, 0);
2011
2012        // First the bare specific types.
2013        let localhost_v4 = Ipv4Addr::new(127, 0, 0, 1);
2014        let encoded = to_bytes(ctxt, &localhost_v4).unwrap();
2015        let decoded: Ipv4Addr = encoded.deserialize().unwrap().0;
2016        assert_eq!(localhost_v4, decoded);
2017
2018        let localhost_v6 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
2019        let encoded = to_bytes(ctxt, &localhost_v6).unwrap();
2020        let decoded: Ipv6Addr = encoded.deserialize().unwrap().0;
2021        assert_eq!(localhost_v6, decoded);
2022
2023        // Now wrapper under the generic IpAddr.
2024        let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
2025        let encoded = to_bytes(ctxt, &localhost_v4).unwrap();
2026        let decoded: IpAddr = encoded.deserialize().unwrap().0;
2027        assert_eq!(localhost_v4, decoded);
2028
2029        let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
2030        let encoded = to_bytes(ctxt, &localhost_v6).unwrap();
2031        let decoded: IpAddr = encoded.deserialize().unwrap().0;
2032        assert_eq!(localhost_v6, decoded);
2033    }
2034
2035    #[cfg(feature = "ostree-tests")]
2036    #[test]
2037    fn ostree_de() {
2038        #[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
2039        struct Summary<'a>(Vec<Repo<'a>>, #[serde(borrow)] HashMap<&'a str, Value<'a>>);
2040
2041        #[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
2042        struct Repo<'a>(&'a str, #[serde(borrow)] Metadata<'a>);
2043
2044        #[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
2045        struct Metadata<'a>(u64, Vec<u8>, #[serde(borrow)] HashMap<&'a str, Value<'a>>);
2046
2047        let encoded = std::fs::read("../test-data/flatpak-summary.dump").unwrap();
2048        let ctxt = Context::new_gvariant(LE, 0);
2049        let encoded = Data::new(encoded, ctxt);
2050        let _: Summary<'_> = encoded.deserialize().unwrap().0;
2051        // If we're able to deserialize all the data successfully, don't bother checking the summary
2052        // data.
2053    }
2054
2055    #[test]
2056    #[cfg(feature = "time")]
2057    fn time() {
2058        // time::Date
2059        let date = time::Date::from_calendar_date(2011, time::Month::June, 21).unwrap();
2060        let ctxt = Context::new_dbus(LE, 0);
2061        let encoded = to_bytes(ctxt, &date).unwrap();
2062        let decoded: time::Date = encoded.deserialize().unwrap().0;
2063        assert_eq!(date, decoded);
2064
2065        // time::Duration
2066        let duration = time::Duration::new(42, 123456789);
2067        let ctxt = Context::new_dbus(LE, 0);
2068        let encoded = to_bytes(ctxt, &duration).unwrap();
2069        let decoded: time::Duration = encoded.deserialize().unwrap().0;
2070        assert_eq!(duration, decoded);
2071
2072        // time::OffsetDateTime
2073        let offset = time::OffsetDateTime::now_utc();
2074        let ctxt = Context::new_dbus(LE, 0);
2075        let encoded = to_bytes(ctxt, &offset).unwrap();
2076        let decoded: time::OffsetDateTime = encoded.deserialize().unwrap().0;
2077        assert_eq!(offset, decoded);
2078
2079        // time::Time
2080        let time = time::Time::from_hms(23, 42, 59).unwrap();
2081        let ctxt = Context::new_dbus(LE, 0);
2082        let encoded = to_bytes(ctxt, &time).unwrap();
2083        let decoded: time::Time = encoded.deserialize().unwrap().0;
2084        assert_eq!(time, decoded);
2085
2086        // time::PrimitiveDateTime
2087        let date = time::PrimitiveDateTime::new(date, time);
2088        let ctxt = Context::new_dbus(LE, 0);
2089        let encoded = to_bytes(ctxt, &date).unwrap();
2090        let decoded: time::PrimitiveDateTime = encoded.deserialize().unwrap().0;
2091        assert_eq!(date, decoded);
2092    }
2093
2094    #[test]
2095    fn recursion_limits() {
2096        let ctxt = Context::new_dbus(LE, 0);
2097        // Total container depth exceeds limit (64)
2098        let mut value = Value::from(0u8);
2099        for _ in 0..64 {
2100            value = Value::Value(Box::new(value));
2101        }
2102        assert!(matches!(
2103            to_bytes(ctxt, &value),
2104            Err(Error::MaxDepthExceeded(MaxDepthExceeded::Container))
2105        ));
2106
2107        // Array depth exceeds limit (32)
2108        let vec = vec![vec![vec![vec![vec![vec![vec![vec![vec![vec![vec![
2109            vec![vec![vec![vec![vec![vec![vec![vec![vec![vec![vec![
2110                vec![vec![vec![vec![vec![vec![vec![vec![vec![vec![vec![
2111                    0u8,
2112                ]]]]]]]]]]],
2113            ]]]]]]]]]]],
2114        ]]]]]]]]]]];
2115        assert!(matches!(
2116            to_bytes(ctxt, &vec),
2117            Err(Error::MaxDepthExceeded(MaxDepthExceeded::Array))
2118        ));
2119
2120        // Struct depth exceeds limit (32)
2121        let tuple = ((((((((((((((((((((((
2122            (((((((((((0u8,),),),),),),),),),),),
2123        ),),),),),),),),),),),),),),),),),),),),),);
2124        assert!(matches!(
2125            to_bytes(ctxt, &tuple),
2126            Err(Error::MaxDepthExceeded(MaxDepthExceeded::Structure))
2127        ));
2128
2129        // total depth exceeds limit (64) with struct, array and variant.
2130        let mut value = Value::from(0u8);
2131        for _ in 0..32 {
2132            value = Value::Value(Box::new(value));
2133        }
2134        let tuple_array =
2135            (
2136                ((((((((((((((((vec![vec![vec![vec![vec![vec![vec![vec![
2137                    vec![vec![vec![vec![vec![vec![vec![vec![value]]]]]]]],
2138                ]]]]]]]],),),),),),),),),),),),),),),),),
2139            );
2140        assert!(matches!(
2141            to_bytes(ctxt, &tuple_array),
2142            Err(Error::MaxDepthExceeded(MaxDepthExceeded::Container))
2143        ));
2144
2145        // TODO:
2146        //
2147        // * Test deserializers.
2148        // * Test gvariant format.
2149    }
2150}