Derive Macro Value
#[derive(Value)]
{
// Attributes available to this derive:
#[zbus]
#[zvariant]
}
Expand description
Implements conversions for your type to/from Value.
Implements TryFrom<Value> and Into<Value> for your type.
§Examples
Simple owned strutures:
use zvariant::{OwnedObjectPath, OwnedValue, Value};
#[derive(Clone, Value, OwnedValue)]
struct OwnedStruct {
owned_str: String,
owned_path: OwnedObjectPath,
}
let s = OwnedStruct {
owned_str: String::from("hi"),
owned_path: OwnedObjectPath::try_from("/blah").unwrap(),
};
let value = Value::from(s.clone());
let _ = OwnedStruct::try_from(value).unwrap();
let value = OwnedValue::try_from(s).unwrap();
let s = OwnedStruct::try_from(value).unwrap();
assert_eq!(s.owned_str, "hi");
assert_eq!(s.owned_path.as_str(), "/blah");Now for the more exciting case of unowned structures:
use zvariant::{ObjectPath, Str};
#[derive(Clone, Value, OwnedValue)]
struct UnownedStruct<'a> {
s: Str<'a>,
path: ObjectPath<'a>,
}
let hi = String::from("hi");
let s = UnownedStruct {
s: Str::from(&hi),
path: ObjectPath::try_from("/blah").unwrap(),
};
let value = Value::from(s.clone());
let s = UnownedStruct::try_from(value).unwrap();
let value = OwnedValue::try_from(s).unwrap();
let s = UnownedStruct::try_from(value).unwrap();
assert_eq!(s.s, "hi");
assert_eq!(s.path, "/blah");Generic structures also supported:
#[derive(Clone, Value, OwnedValue)]
struct GenericStruct<S, O> {
field1: S,
field2: O,
}
let s = GenericStruct {
field1: String::from("hi"),
field2: OwnedObjectPath::try_from("/blah").unwrap(),
};
let value = Value::from(s.clone());
let _ = GenericStruct::<String, OwnedObjectPath>::try_from(value).unwrap();
let value = OwnedValue::try_from(s).unwrap();
let s = GenericStruct::<String, OwnedObjectPath>::try_from(value).unwrap();
assert_eq!(s.field1, "hi");
assert_eq!(s.field2.as_str(), "/blah");Enums also supported but currently only with unit variants:
#[derive(Debug, PartialEq, Value, OwnedValue)]
// Default representation is `u32`.
#[repr(u8)]
enum Enum {
Variant1 = 0,
Variant2,
}
let value = Value::from(Enum::Variant1);
let e = Enum::try_from(value).unwrap();
assert_eq!(e, Enum::Variant1);
assert_eq!(e as u8, 0);
let value = OwnedValue::try_from(Enum::Variant2).unwrap();
let e = Enum::try_from(value).unwrap();
assert_eq!(e, Enum::Variant2);String-encoded enums are also supported:
#[derive(Debug, PartialEq, Value, OwnedValue)]
#[zvariant(signature = "s")]
enum StrEnum {
Variant1,
Variant2,
}
let value = Value::from(StrEnum::Variant1);
let e = StrEnum::try_from(value).unwrap();
assert_eq!(e, StrEnum::Variant1);
let value = OwnedValue::try_from(StrEnum::Variant2).unwrap();
let e = StrEnum::try_from(value).unwrap();
assert_eq!(e, StrEnum::Variant2);§Renaming fields
§Auto Renaming
The macro supports specifying a Serde-like #[zvariant(rename_all = "case")] attribute on
structures. The attribute allows to rename all the fields from snake case to another case
automatically.
Currently the macro supports the following values for case:
"lowercase""UPPERCASE""PascalCase""camelCase""snake_case""kebab-case"
§Individual Fields
It’s still possible to specify custom names for individual fields using the
#[zvariant(rename = "another-name")] attribute even when the rename_all attribute is
present.
Here is an example using both rename and rename_all:
#[derive(Clone, Value, OwnedValue)]
#[zvariant(signature = "dict", rename_all = "PascalCase")]
struct RenamedStruct {
#[zvariant(rename = "MyValue")]
field1: String,
field2: String,
}
let s = RenamedStruct {
field1: String::from("hello"),
field2: String::from("world")
};
let v = Value::from(s);
let d = Dict::try_from(v).unwrap();
let hm: HashMap<String, String> = HashMap::try_from(d).unwrap();
assert_eq!(hm.get("MyValue").unwrap().as_str(), "hello");
assert_eq!(hm.get("Field2").unwrap().as_str(), "world");§Dictionary encoding
For treating your type as a dictionary, you can use the signature = "dict" attribute. See
Type for more details and an example use. Please note that this macro can only handle
dict or a{sv} values. All other values will be ignored.