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 modified form of this format, GVariant is very commonly used for efficient storage of arbitrary data and is also supported by this crate.
Since version 2.0, the API is serde-based and hence you'll find it very intuitive if you're already familiar with serde. If you're not familiar with serde, you may want to first read its tutorial before learning further about this crate.
Serialization and deserialization is achieved through the toplevel functions:
use HashMap; use ; use ; use LE; // All serialization and deserialization API, needs a context. let ctxt = new_dbus; // You can also use the more efficient GVariant format: // let ctxt = Context::<LE>::new_gvariant(0); // i16 let encoded = to_bytes.unwrap; let decoded: i16 = from_slice.unwrap; assert_eq!; // strings let encoded = to_bytes.unwrap; let decoded: &str = from_slice.unwrap; assert_eq!; // tuples let t = ; let encoded = to_bytes.unwrap; let decoded: = from_slice.unwrap; assert_eq!; // Vec let v = vec!; let encoded = to_bytes.unwrap; let decoded: = from_slice.unwrap; assert_eq!; // Dictionary let mut map: = new; map.insert; map.insert; let encoded = to_bytes.unwrap; let decoded: = from_slice.unwrap; assert_eq!; assert_eq!; // derive macros to handle custom types. assert_eq!; let s = Struct ; let ctxt = new_dbus; let encoded = to_bytes.unwrap; let decoded: Struct = from_slice.unwrap; assert_eq!; // It can handle enums too, just that all variants must have the same number and types of fields. // Names of fields don't matter though. You can make use of `Value` or `OwnedValue` if you want to // encode different data in different fields. // Enum encoding uses a `u32` to denote the variant index. For unit-type enums that's all that's // needed so the signature is just `u` but complex enums are encoded as a structure whose first // field is the variant index and the second one is the field(s). assert_eq!; let e = Variant3 ; let encoded = to_bytes.unwrap; let decoded: Enum = from_slice.unwrap; assert_eq!; // W/o `repr` spec, `u32` is assumed. assert_eq!; let encoded = to_bytes.unwrap; let e: UnitEnum = from_slice.unwrap; assert_eq!; // Unit enums can also be (de)serialized as strings. assert_eq!;
Apart from the obvious requirement of
EncodingContext instance by the main serialization and
deserialization API, the type being serialized or deserialized must also implement
trait in addition to
Deserialize, respectively. Please refer to
module documentation for more details.
Most of the basic types of D-Bus match 1-1 with all the primitive Rust types. The only two
ObjectPath, which are really just strings. These types
are covered by the
Similarly, most of the container types also map nicely to the usual Rust types and
collections (as can be seen in the example code above). The only note worthy exception being
ARRAY type. As arrays in Rust are fixed-sized, serde treats them as tuples and so does this
crate. This means they are encoded as STRUCT type of D-Bus. If you need to serialize to, or
deserialize from a D-Bus array, you'll need to use a slice (array can easily be converted to a
Vec or an
D-Bus string types, including
ObjectPath, require one additional
restriction that strings in Rust do not. They must not contain any interior null bytes (
Encoding/Decoding strings that contain this character will return an error.
The generic D-Bus type,
VARIANT is represented by
Value, an enum that holds exactly one
value of any of the other types. Please refer to
Value module documentation for examples.
std is currently a hard requirement, optional
no-std support is planned in the future.
On the other hand,
noalloc support is not planned as it will be extremely difficult to
accomplish. However, community contribution can change that. 😊