@@ -11,7 +11,7 @@ use syn::{
1111 ImplItem , ImplItemFn , ItemImpl ,
1212 Lit :: Str ,
1313 Meta , MetaNameValue , PatType , PathArguments , ReturnType , Signature , Token , Type , TypePath ,
14- Visibility ,
14+ TypeReference , Visibility ,
1515} ;
1616use zvariant_utils:: { case, def_attrs} ;
1717
@@ -983,6 +983,18 @@ pub fn expand(args: Punctuated<Meta, Token![,]>, mut input: ItemImpl) -> syn::Re
983983 } )
984984}
985985
986+ fn maybe_unref_ty ( ty : & Type ) -> Option < & Type > {
987+ fn should_unref ( v : & TypeReference ) -> bool {
988+ // &str is special and we can deserialize to it, unlike other reference types.
989+ !matches ! ( * v. elem, Type :: Path ( ref p) if p. path. is_ident( "str" ) )
990+ }
991+
992+ match * ty {
993+ Type :: Reference ( ref v) if should_unref ( v) => Some ( & v. elem ) ,
994+ _ => None ,
995+ }
996+ }
997+
986998fn get_args_from_inputs (
987999 inputs : & [ PatType ] ,
9881000 method_type : MethodType ,
@@ -1071,7 +1083,7 @@ fn get_args_from_inputs(
10711083 } ;
10721084 } else {
10731085 args_names. push ( pat_ident ( input) . unwrap ( ) ) ;
1074- tys. push ( & input. ty ) ;
1086+ tys. push ( & * input. ty ) ;
10751087 }
10761088 }
10771089
@@ -1085,15 +1097,36 @@ fn get_args_from_inputs(
10851097 _ => (
10861098 quote ! { let hdr = message. header( ) ; } ,
10871099 quote ! { let msg_body = message. body( ) ; } ,
1088- quote ! {
1089- let ( #( #args_names) , * ) : ( #( #tys) , * ) =
1090- match msg_body. deserialize( ) {
1091- :: std:: result:: Result :: Ok ( r) => r,
1092- :: std:: result:: Result :: Err ( e) => {
1093- let err = <#zbus:: fdo:: Error as :: std:: convert:: From <_>>:: from( e) ;
1094- return connection. reply_dbus_error( & hdr, err) . await ;
1100+ {
1101+ let mut unrefed_indices = vec ! [ ] ;
1102+ let owned_tys = tys
1103+ . iter ( )
1104+ . enumerate ( )
1105+ . map ( |( i, ty) | {
1106+ let owned = maybe_unref_ty ( ty) ;
1107+ if owned. is_some ( ) {
1108+ unrefed_indices. push ( i) ;
10951109 }
1096- } ;
1110+ owned. unwrap_or ( ty)
1111+ } )
1112+ . collect :: < Vec < _ > > ( ) ;
1113+ let mut q = quote ! {
1114+ let ( #( #args_names) , * ) : ( #( #owned_tys) , * ) =
1115+ match msg_body. deserialize( ) {
1116+ :: std:: result:: Result :: Ok ( r) => r,
1117+ :: std:: result:: Result :: Err ( e) => {
1118+ let err = <#zbus:: fdo:: Error as :: std:: convert:: From <_>>:: from( e) ;
1119+ return connection. reply_dbus_error( & hdr, err) . await ;
1120+ }
1121+ } ;
1122+ } ;
1123+ for index in unrefed_indices {
1124+ let arg_name = & args_names[ index] ;
1125+ q. extend ( quote ! {
1126+ let #arg_name = & #arg_name;
1127+ } ) ;
1128+ }
1129+ q
10971130 } ,
10981131 ) ,
10991132 } ;
0 commit comments