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