]> git.proxmox.com Git - proxmox.git/commitdiff
macro: partial support for automatic Default derivation
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 19 Jul 2019 13:17:25 +0000 (15:17 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 19 Jul 2019 13:17:25 +0000 (15:17 +0200)
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
proxmox-api-macro/src/api_macro.rs
proxmox-api-macro/src/parsing.rs

index 27720f3e27b02afbfef3872904282782422f0b60..7f5170b80684b2850286862f7ba0101aeb8de3c9 100644 (file)
@@ -488,6 +488,12 @@ fn handle_struct_named(
         .ok_or_else(|| c_format_err!(definition.span(), "missing 'fields' entry"))?
         .expect_object()?;
 
+    let derive_default = definition
+        .remove("derive_default")
+        .map(|e| e.expect_lit_bool_direct())
+        .transpose()?
+        .unwrap_or(false);
+
     let field_count = item.named.len();
 
     let type_s = type_ident.to_string();
@@ -506,6 +512,7 @@ fn handle_struct_named(
     let mut field_name_matches = TokenStream::new(); // ` "member0" => 0, "member1" => 1, `
     let mut field_value_matches = TokenStream::new();
     let mut auto_methods = TokenStream::new();
+    let mut default_impl = TokenStream::new();
 
     let mut mem_id: isize = 0;
     for field in item.named.iter() {
@@ -576,9 +583,31 @@ fn handle_struct_named(
                     ::proxmox::api::meta::OrDefault::set(&mut self.#field_ident, value)
                 }
             });
+
+            default_impl.extend(quote_spanned! { field_span =>
+                #field_ident: #default.into(),
+            });
+        } else {
+            if derive_default {
+                default_impl.extend(quote_spanned! { field_span =>
+                    #field_ident: Default::default(),
+                });
+            }
         }
     }
 
+    if derive_default {
+        default_impl = quote_spanned! { item.span() =>
+            impl ::std::default::Default for #type_ident {
+                fn default() -> Self {
+                    Self {
+                        #default_impl
+                    }
+                }
+            }
+        };
+    }
+
     let description = common.description;
     let parse_cli = common.cli.quote(&type_ident);
     Ok(quote_spanned! { item.span() =>
@@ -693,6 +722,8 @@ fn handle_struct_named(
             }
         }
 
+        #default_impl
+
         impl #type_ident {
             #auto_methods
         }
index bb8dacef7dfa5611b16aacdb96a2915a3a3076ca..00042317561e8a2252d0268897f357856e9261bb 100644 (file)
@@ -246,6 +246,10 @@ impl Expression {
         }
     }
 
+    pub fn expect_lit_bool_direct(self) -> Result<bool, Error> {
+        Ok(self.expect_lit_bool()?.value)
+    }
+
     pub fn expect_expr(self) -> Result<syn::Expr, Error> {
         match self {
             Expression::Expr(expr) => Ok(expr),