[−][src]Crate zvariant
This crate provides API for encoding/decoding of data to/from D-Bus wire format. This binary wire format is simple and very efficient and hence useful outside of D-Bus context as well. A slightly modified form of this format, GVariant is also very common and will be supported by a future version of this crate.
The core traits are Encode
and Decode
, for (surprise surprise) encoding and decoding of data. All data types
that can be encoded to wire-format, implement these traits. As decoding require allocation, one exception here is
&str
. It only implements Encode
, while its owned sibling, String
implements both traits.
All data types have a signature, which is a string denoting the type in question. These data types are divided into
two groups, basic and container. Most of the basic types match 1-1 with all the primitive Rust types. The only two
exceptions being, Signature
and ObjectPath
, which are really just strings. The marker trait, Basic
, is
implemented by all the basic types, except f64
. There is also SimpleDecode
trait, which is for types (mostly
basic) whose signature is always the same.
For container types, we provide custom data types:
Array
: An unordered collection of items of the same type. API is provided to transform this into, and from aVec
.Structure
: An ordered collection of items of arbitrary types.DictEntry
: A dictionary entry as a key-value pair. The key must be a basic type.Dict
: A dictionary as anArray
ofDictEntry
. API is provided to transform this into, and from aHashMap
.Variant
: A generic container, in the form of an enum that holds exactly one value of any of the other types.
Examples
Here are some simple encoding and decoding examples:
use zvariant::{Encode, EncodingFormat, SimpleDecode}; // Encode a string let format = EncodingFormat::default(); let encoding = "Hello world!".encode(format); assert!(encoding.len() == 17); // and the decode it from the encoded form let s = String::decode_simple(encoding, format).unwrap(); assert!(s == "Hello world!");
use zvariant::{Decode, Encode, EncodingFormat, Variant}; // Create a Variant from an i16 let v = i16::max_value().to_variant(); assert!(*i16::from_variant(&v).unwrap() == i16::max_value()); assert!(i16::is(&v)); // Encode it let format = EncodingFormat::default(); let encoding = v.encode_value(format); assert!(encoding.len() == 2); // Decode it back let v = Variant::from_data(encoding, v.value_signature(), format).unwrap(); assert!(i16::take_from_variant(v).unwrap() == i16::max_value());
And a complex example:
use core::convert::TryFrom; use std::collections::HashMap; use zvariant::{Array, Decode, Dict, Encode, EncodingFormat, Structure}; // We chould directly create an Array of DictEntry too let mut map: HashMap<i64, &str> = HashMap::new(); map.insert(1, "123"); map.insert(2, "456"); let dict: Dict = map.into(); let array = Array::try_from(dict).unwrap(); // Create our not-so-simple structure let s = Structure::new() .add_field(u8::max_value()) .add_field(u32::max_value()) .add_field( Structure::new() .add_field(i64::max_value()) .add_field(true) .add_field( Structure::new() .add_field(i64::max_value()) .add_field(std::f64::MAX), ), ) .add_field("hello") .add_field(array); // Encode the structure let format = EncodingFormat::default(); let encoding = s.encode(format); // The HashMap is unordered so we can't rely on items to be in a specific order during the // transformation to Vec, and size depends on the order of items because of padding rules. assert!(encoding.len() == 88 || encoding.len() == 92); // Then we decode the structure from the encoded value let s = Structure::decode(encoding, s.signature(), format).unwrap(); assert!(s.signature() == "(yu(xb(xd))sa{xs})"); // Check all the fields are as expected let fields = s.fields(); assert!(u8::is(&fields[0])); assert!(*u8::from_variant(&fields[0]).unwrap() == u8::max_value()); assert!(u32::is(&fields[1])); assert!(*u32::from_variant(&fields[1]).unwrap() == u32::max_value()); assert!(Structure::is(&fields[2])); let inner = Structure::from_variant(&fields[2]).unwrap(); let inner_fields = inner.fields(); assert!(i64::is(&inner_fields[0])); assert!(*i64::from_variant(&inner_fields[0]).unwrap() == i64::max_value()); assert!(bool::is(&inner_fields[1])); assert!(*bool::from_variant(&inner_fields[1]).unwrap()); assert!(String::is(&fields[3])); assert!(String::from_variant(&fields[3]).unwrap() == "hello");
Structs
Array | An unordered collection of items of the same type. |
Dict | |
DictEntry | A dictionary entry as a key-value pair. |
ObjectPath | String that identifies objects at a given destination on the D-Bus bus. |
SharedData | Immutable slice of an underlying byte buffer. |
Signature | String that identifies the type of an encoded value. |
Structure | An ordered collection of items of arbitrary types. |
Enums
EncodingFormat | The encoding format. |
Variant | A generic container, in the form of an enum that holds exactly one value of any of the other types. |
VariantError |
Traits
Basic | Marker trait for basic types. |
Decode | Trait for decoding of varius types from encoded form. |
Encode | Trait for encoding of varius types. |
SimpleDecode | Simpler sibling of |