1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
//! 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 a //! [`Vec`]. //! * [`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 an [`Array`] of [`DictEntry`]. API is provided to transform this into, and from a //! [`HashMap`]. //! * [`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"); //! ``` //! [D-Bus]: https://dbus.freedesktop.org/doc/dbus-specification.html //! [GVariant]: https://developer.gnome.org/glib/stable/glib-GVariant.html //! [`Decode`]: trait.Decode.html //! [`Encode`]: trait.Encode.html //! [`Signature`]: struct.Signature.html //! [`ObjectPath`]: struct.ObjectPath.html //! [`Basic`]: trait.Basic.html //! [except `f64`]: trait.Basic.html //! [`SimpleDecode`]: trait.SimpleDecode.html //! [`Array`]: struct.Array.html //! [`Structure`]: struct.Structure.html //! [`DictEntry`]: struct.DictEntry.html //! [`Dict`]: struct.Dict.html //! [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html //! [`HashMap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html //! [`Variant`]: enum.Variant.html mod basic; pub use basic::*; mod variant; pub use variant::*; mod decode; pub use decode::*; mod encode; pub use encode::*; mod variant_error; pub use variant_error::*; mod str; pub use crate::str::*; mod signature; pub use crate::signature::*; mod object_path; pub use crate::object_path::*; mod simple_decode; pub use simple_decode::*; mod structure; pub use structure::*; mod array; pub use array::*; mod dict_entry; pub use dict_entry::*; mod dict; pub use dict::*; mod shared_data; pub use shared_data::*; mod utils;