Skip to content

Commit

Permalink
🥅 zm: interface-generated proxy should use the same error types
Browse files Browse the repository at this point in the history
If user specifies a Result type as return type of a method, the generated
proxy should use the same error types. We might need to add an attribute
to control in the future, as this as this may not always be what the user
wants.

We should do this because if we hardcode the error type to be
`zbus::Error`, the API will have to break if one decides to replace a
`proxy` use with this new ability of `interface` and they had their
`proxy` return a specific error type. This for example is the case for
`zbus::fdo` API, which we want to convert in the future.

Speaking of API break, this change itself is an API break but
practically speaking the chances of someone already making use of the
newly added feature of generating proxy from interface is pretty low (on
the Matrix channel people didn't even know it was added), let alone them
using a custom error in interface methods while not in proxy as well.
  • Loading branch information
zeenix committed Jun 29, 2024
1 parent 0ece0f0 commit ab2cae9
Showing 1 changed file with 41 additions and 7 deletions.
48 changes: 41 additions & 7 deletions zbus_macros/src/iface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ pub fn expand<T: AttrParse + Into<ImplAttrs>, M: AttrParse + Into<MethodAttrs>>(
}

if let Some(proxy) = &mut proxy {
proxy.add_method(info, &properties);
proxy.add_method(info, &properties)?;
}
}

Expand Down Expand Up @@ -1335,7 +1335,11 @@ impl Proxy {
}
}

fn add_method(&mut self, method_info: MethodInfo, properties: &BTreeMap<String, Property<'_>>) {
fn add_method(
&mut self,
method_info: MethodInfo,
properties: &BTreeMap<String, Property<'_>>,
) -> syn::Result<()> {
let inputs: Punctuated<PatType, Comma> = method_info
.typed_inputs
.iter()
Expand All @@ -1345,9 +1349,38 @@ impl Proxy {
})
.cloned()
.collect();
let ret = get_return_type(&method_info.output)
.map(|r| quote!(#r))
.unwrap_or(quote!(()));
let zbus = &self.zbus;
let ret = match &method_info.output {
ReturnType::Type(_, ty) => {
let ty = ty.as_ref();

if let Type::Path(p) = ty {
let is_result_output = p
.path
.segments
.last()
.ok_or_else(|| Error::new_spanned(ty, "unsupported return type"))?
.ident
== "Result";
if is_result_output {
let is_prop = matches!(method_info.method_type, MethodType::Property(_));

if is_prop {
// Proxy methods always return `zbus::Result<T>`
let inner_ty = get_result_inner_type(p)?;
quote! { #zbus::Result<#inner_ty> }
} else {
quote! { #ty }
}
} else {
quote! { #zbus::Result<#ty> }
}
} else {
quote! { #zbus::Result<#ty> }
}
}
ReturnType::Default => quote! { #zbus::Result<()> },
};
let ident = &method_info.ident;
let member_name = method_info.member_name;
let mut proxy_method_attrs = quote! { name = #member_name, };
Expand Down Expand Up @@ -1386,14 +1419,15 @@ impl Proxy {
}
}
let cfg_attrs = method_info.cfg_attrs;
let zbus = &self.zbus;
let doc_attrs = method_info.doc_attrs;
self.methods.extend(quote! {
#(#cfg_attrs)*
#(#doc_attrs)*
#[zbus(#proxy_method_attrs)]
fn #ident(&self, #inputs) -> #zbus::Result<#ret>;
fn #ident(&self, #inputs) -> #ret;
});

Ok(())
}

fn gen(&self) -> TokenStream {
Expand Down

0 comments on commit ab2cae9

Please sign in to comment.