zvariant/
lib.rs

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