@@ -86,6 +86,9 @@ enum PropAttr {
86
86
// Builder(Punctuated(required_params), Optionals(TokenStream))
87
87
Builder ( Punctuated < syn:: Expr , Token ! [ , ] > , TokenStream2 ) ,
88
88
89
+ // ident
90
+ Nullable ,
91
+
89
92
// ident [= expr]
90
93
Get ( Option < syn:: Expr > ) ,
91
94
Set ( Option < syn:: Expr > ) ,
@@ -151,6 +154,7 @@ impl Parse for PropAttr {
151
154
} else {
152
155
// attributes with only the identifier name
153
156
match & * name_str {
157
+ "nullable" => PropAttr :: Nullable ,
154
158
"get" => PropAttr :: Get ( None ) ,
155
159
"set" => PropAttr :: Set ( None ) ,
156
160
"readwrite" | "read_only" | "write_only" => {
@@ -171,6 +175,7 @@ impl Parse for PropAttr {
171
175
172
176
#[ derive( Default ) ]
173
177
struct ReceivedAttrs {
178
+ nullable : bool ,
174
179
get : Option < MaybeCustomFn > ,
175
180
set : Option < MaybeCustomFn > ,
176
181
override_class : Option < syn:: Type > ,
@@ -197,6 +202,7 @@ impl Parse for ReceivedAttrs {
197
202
impl ReceivedAttrs {
198
203
fn set_from_attr ( & mut self , attr : PropAttr ) {
199
204
match attr {
205
+ PropAttr :: Nullable => self . nullable = true ,
200
206
PropAttr :: Get ( some_fn) => self . get = Some ( some_fn. into ( ) ) ,
201
207
PropAttr :: Set ( some_fn) => self . set = Some ( some_fn. into ( ) ) ,
202
208
PropAttr :: Name ( lit) => self . name = Some ( lit) ,
@@ -223,6 +229,7 @@ struct PropDesc {
223
229
name : syn:: LitStr ,
224
230
override_class : Option < syn:: Type > ,
225
231
override_interface : Option < syn:: Type > ,
232
+ nullable : bool ,
226
233
get : Option < MaybeCustomFn > ,
227
234
set : Option < MaybeCustomFn > ,
228
235
member : Option < syn:: Ident > ,
@@ -238,6 +245,7 @@ impl PropDesc {
238
245
attrs : ReceivedAttrs ,
239
246
) -> syn:: Result < Self > {
240
247
let ReceivedAttrs {
248
+ nullable,
241
249
get,
242
250
set,
243
251
override_class,
@@ -280,6 +288,7 @@ impl PropDesc {
280
288
name,
281
289
override_class,
282
290
override_interface,
291
+ nullable,
283
292
get,
284
293
set,
285
294
member,
@@ -514,8 +523,23 @@ fn expand_wrapper_getset_properties(props: &[PropDesc]) -> TokenStream2 {
514
523
let is_construct_only = p. builder_fields . iter ( ) . any ( |( k, _) | * k == "construct_only" ) ;
515
524
let setter = ( p. set . is_some ( ) && !is_construct_only) . then ( || {
516
525
let ident = format_ident ! ( "set_{}" , ident) ;
517
- quote ! ( pub fn #ident<' a>( & self , value: impl std:: borrow:: Borrow <<<#ty as #crate_ident:: Property >:: Value as #crate_ident:: HasParamSpec >:: SetValue >) {
518
- self . set_property_from_value( #name, & :: std:: convert:: From :: from( std:: borrow:: Borrow :: borrow( & value) ) )
526
+ let target_ty = quote ! ( <<#ty as #crate_ident:: Property >:: Value as #crate_ident:: HasParamSpec >:: SetValue ) ;
527
+ let set_ty = if p. nullable {
528
+ quote ! ( Option <impl std:: borrow:: Borrow <#target_ty>>)
529
+ } else {
530
+ quote ! ( impl std:: borrow:: Borrow <#target_ty>)
531
+ } ;
532
+ let upcasted_borrowed_value = if p. nullable {
533
+ quote ! (
534
+ value. as_ref( ) . map( |v| std:: borrow:: Borrow :: borrow( v) )
535
+ )
536
+ } else {
537
+ quote ! (
538
+ std:: borrow:: Borrow :: borrow( & value)
539
+ )
540
+ } ;
541
+ quote ! ( pub fn #ident<' a>( & self , value: #set_ty) {
542
+ self . set_property_from_value( #name, & :: std:: convert:: From :: from( #upcasted_borrowed_value) )
519
543
} )
520
544
} ) ;
521
545
let span = p. attrs_span ;
0 commit comments