Closed jobfeikens closed 4 months ago
LGTM. Curious what you're going to use it for?
LGTM. Curious what you're going to use it for?
I wanted to implement Append for my custom type but I needed to know the inner signature before calling either append_dict or append_array.
impl Append for DBusValue {
fn append_by_ref(&self, iter: &mut IterAppend) {
match self {
DBusValue::U8(value) => value.append_by_ref(iter),
DBusValue::Bool(value) => value.append_by_ref(iter),
DBusValue::I16(value) => value.append_by_ref(iter),
DBusValue::U16(value) => value.append_by_ref(iter),
DBusValue::I32(value) => value.append_by_ref(iter),
DBusValue::U32(value) => value.append_by_ref(iter),
DBusValue::I64(value) => value.append_by_ref(iter),
DBusValue::U64(value) => value.append_by_ref(iter),
DBusValue::F64(value) => value.append_by_ref(iter),
DBusValue::UnixFd(value) => value.append_by_ref(iter),
DBusValue::String(value) => value.append_by_ref(iter),
DBusValue::ObjectPath(value) => value.deref().append_by_ref(iter),
DBusValue::Signature(value) => value.deref().append_by_ref(iter),
DBusValue::Variant(value) => iter.append_variant(
&Signature::new(value_signature(&value)).unwrap(),
|iter| {
value.append_by_ref(iter);
},
),
DBusValue::Array(value) => {
let signature_iter = SignatureIter::new(&value.signature);
let array_iter = signature_iter.recurse();
if array_iter.current_type() == DBUS_TYPE_DICT_ENTRY {
let mut dict_entry_iter = array_iter.recurse();
let key_signature = dict_entry_iter.current_signature();
dict_entry_iter.next();
let value_signature = dict_entry_iter.current_signature();
iter.append_dict(&key_signature, &value_signature, |iter| {
for value in &value.values {
value.append_by_ref(iter);
}
})
} else {
let inner_signature = array_iter.current_signature();
iter.append_array(&inner_signature, |iter| {
for value in &value.values {
value.append_by_ref(iter);
}
})
}
}
DBusValue::Struct(values) => iter.append_struct(|iter| {
for value in values {
value.append_by_ref(iter);
}
}),
DBusValue::DictEntry { key, value } => {
iter.append_dict_entry(|iter| {
key.append_by_ref(iter);
value.append_by_ref(iter);
})
}
}
}
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum DBusValue {
#[serde(rename = "y")]
U8(u8),
#[serde(rename = "b")]
Bool(bool),
#[serde(rename = "n")]
I16(i16),
#[serde(rename = "q")]
U16(u16),
#[serde(rename = "i")]
I32(i32),
#[serde(rename = "u")]
U32(u32),
#[serde(rename = "x")]
I64(i64),
#[serde(rename = "t")]
U64(u64),
#[serde(rename = "d")]
F64(f64),
#[serde(rename = "h")]
UnixFd(RawFd),
#[serde(rename = "s")]
String(String),
#[serde(rename = "o")]
ObjectPath(
#[serde(
serialize_with = "serialize::serialize_path",
deserialize_with = "serialize::deserialize_path"
)]
dbus::Path<'static>,
),
#[serde(rename = "g")]
Signature(
#[serde(
serialize_with = "serialize::serialize_signature",
deserialize_with = "serialize::deserialize_signature"
)]
dbus::Signature<'static>,
),
#[serde(rename = "v")]
Variant(Box<DBusValue>), // TODO: make sure inner value isnt a dict entry or append_by_ref will fail
#[serde(rename = "a", rename_all = "camelCase")]
Array(ArrayValue),
#[serde(rename = "r")]
Struct(Vec<DBusValue>),
#[serde(rename = "e")]
DictEntry {
key: Box<DBusValue>,
value: Box<DBusValue>,
},
}
#[derive(Debug, Serialize)]
pub struct ArrayValue {
// Signature of the contained values
// (This includes 'a' because dict entries' signatures are not valid on their own)
#[serde(serialize_with = "serialize::serialize_inner_signature")]
pub(crate) signature: dbus::Signature<'static>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) values: Vec<DBusValue>,
}
I added some missing methods to the libdbus-sys crate.