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