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