Skip to content

Commit

Permalink
Don't require an owned value for property setters.
Browse files Browse the repository at this point in the history
I wrote this as I was thinking about #1180, but not sure it's worth the
complexity. If you think there are some other things that might use it,
please go ahead and merge it, otherwise feel free to close :)
  • Loading branch information
emilio committed Dec 27, 2024
1 parent 2181232 commit 577de75
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 13 deletions.
4 changes: 2 additions & 2 deletions zbus/src/fdo/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl Properties {
&self,
interface_name: InterfaceName<'_>,
property_name: &str,
value: Value<'_>,
value: &Value<'_>,
#[zbus(object_server)] server: &ObjectServer,
#[zbus(connection)] connection: &Connection,
#[zbus(header)] header: Header<'_>,
Expand All @@ -79,7 +79,7 @@ impl Properties {

match iface.instance.read().await.set(
property_name,
&value,
value,
server,
connection,
Some(&header),
Expand Down
2 changes: 1 addition & 1 deletion zbus/src/proxy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ impl<'a> Proxy<'a> {
T: 't + Into<Value<'t>>,
{
self.properties_proxy()
.set(self.inner.interface.as_ref(), property_name, value.into())
.set(self.inner.interface.as_ref(), property_name, &value.into())
.await
}

Expand Down
53 changes: 43 additions & 10 deletions zbus_macros/src/iface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use syn::{
ImplItem, ImplItemFn, ItemImpl,
Lit::Str,
Meta, MetaNameValue, PatType, PathArguments, ReturnType, Signature, Token, Type, TypePath,
Visibility,
TypeReference, Visibility,
};
use zvariant_utils::{case, def_attrs};

Expand Down Expand Up @@ -983,6 +983,18 @@ pub fn expand(args: Punctuated<Meta, Token![,]>, mut input: ItemImpl) -> syn::Re
})
}

fn maybe_unref_ty(ty: &Type) -> Option<&Type> {
fn should_unref(v: &TypeReference) -> bool {
// &str is special and we can deserialize to it, unlike other reference types.
!matches!(*v.elem, Type::Path(ref p) if p.path.is_ident("str"))
}

match *ty {
Type::Reference(ref v) if should_unref(v) => Some(&v.elem),
_ => None,
}
}

fn get_args_from_inputs(
inputs: &[PatType],
method_type: MethodType,
Expand Down Expand Up @@ -1071,7 +1083,7 @@ fn get_args_from_inputs(
};
} else {
args_names.push(pat_ident(input).unwrap());
tys.push(&input.ty);
tys.push(&*input.ty);
}
}

Expand All @@ -1085,15 +1097,36 @@ fn get_args_from_inputs(
_ => (
quote! { let hdr = message.header(); },
quote! { let msg_body = message.body(); },
quote! {
let (#(#args_names),*): (#(#tys),*) =
match msg_body.deserialize() {
::std::result::Result::Ok(r) => r,
::std::result::Result::Err(e) => {
let err = <#zbus::fdo::Error as ::std::convert::From<_>>::from(e);
return connection.reply_dbus_error(&hdr, err).await;
{
let mut unrefed_indices = vec![];
let owned_tys = tys
.iter()
.enumerate()
.map(|(i, ty)| {
let owned = maybe_unref_ty(ty);
if owned.is_some() {
unrefed_indices.push(i);
}
};
owned.unwrap_or(ty)
})
.collect::<Vec<_>>();
let mut q = quote! {
let (#(#args_names),*): (#(#owned_tys),*) =
match msg_body.deserialize() {
::std::result::Result::Ok(r) => r,
::std::result::Result::Err(e) => {
let err = <#zbus::fdo::Error as ::std::convert::From<_>>::from(e);
return connection.reply_dbus_error(&hdr, err).await;
}
};
};
for index in unrefed_indices {
let arg_name = &args_names[index];
q.extend(quote! {
let #arg_name = &#arg_name;
});
}
q
},
),
};
Expand Down

0 comments on commit 577de75

Please sign in to comment.