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