started default function

This commit is contained in:
scbj
2025-01-16 18:08:23 +01:00
parent db8c62c476
commit 1abb470dd6
4 changed files with 243 additions and 1 deletions
@@ -83,6 +83,43 @@ pub fn gen_to_string(name: &Ident, fields: &Punctuated<Field, Comma>) -> TokenSt
}
}
pub fn gen_default(fields: &Punctuated<Field, Comma>) -> TokenStream {
let mut defaults: TokenStream = TokenStream::new();
'fields: for field in fields.iter() {
let attr = &field.attrs;
let name = match &field.ident {
Some(value) => value,
// skip anonymous fields
None => continue 'fields,
};
let ty = &field.ty;
for attribute in attr {
if let Attribute{ meta: Meta::Path( Path{segments: attr_name, ..} ), .. } = attribute {
match attr_name.first() {
Some(value) => if value.ident == "default_value" {
let default_value = get_attribute_value(attribute);
defaults.extend(quote! {
#name: #default_value,
});
} else if value.ident == "nested_config" {
defaults.extend(quote! {
#name: #ty.default()?;
});
},
None => (),
}
}
}
};
quote!{
/// returns an instance with default values
pub fn default(&mut self) -> std::io::Result<()> {
#defaults
Ok(())
}
}
}
pub fn gen_config_assignments(fields: &Punctuated<Field, Comma>, config_map_name: &syn::Ident) -> TokenStream {
let mut assignments : TokenStream = TokenStream::new();
'fields: for field in fields.iter() {
@@ -127,3 +164,7 @@ pub fn gen_config_assignments(fields: &Punctuated<Field, Comma>, config_map_name
assignments
}
fn get_attribute_value(attribute: &Attribute) -> TokenStream {
//if let Attribute{ Meta::List }
TokenStream::new()
}
+4 -1
View File
@@ -11,7 +11,7 @@ use generator_functions::*;
/// which parses a string and fills the fills recognised values into the struct
/// - implements `write_default_config() -> Result<String>`
/// which write a default configuration, in case the documentation is lacking
#[proc_macro_derive(ConfigParser, attributes(nested_config, no_config, style_config))]
#[proc_macro_derive(ConfigParser, attributes(default_value, nested_config, no_config, style_config))]
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let name = &ast.ident;
@@ -21,6 +21,9 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
} else {
panic!("the macro `ConfigParser` applies only to structs!");
};
if name.to_string() == "GeneralSettings" {
println!("ast = {:#?}", ast);
}
let assignments: TokenStream = gen_config_assignments(fields, &config_name);
let func_parse_string: TokenStream = gen_parse_from_string(&config_name, &assignments);
let func_parse_map: TokenStream = gen_parse_from_map(&config_name, &assignments);
+3
View File
@@ -20,8 +20,11 @@ pub struct Config {
#[derive(Debug, Clone, Default, ConfigParser)]
pub struct GeneralSettings {
#[default_value(false)]
pub show_stack_on_push: bool,
#[no_config]
pub show_stack_on_pop: bool,
#[default_value = false]
pub show_books_on_bookmark: bool,
}
+195
View File
@@ -0,0 +1,195 @@
ast = DeriveInput {
attrs: [],
vis: Visibility::Public(
Pub,
),
ident: Ident {
ident: "GeneralSettings",
span: #0 bytes(10021..10036),
},
generics: Generics {
lt_token: None,
params: [],
gt_token: None,
where_clause: None,
},
data: Data::Struct {
struct_token: Struct,
fields: Fields::Named {
brace_token: Brace,
named: [
Field {
attrs: [
Attribute {
pound_token: Pound,
style: AttrStyle::Outer,
bracket_token: Bracket,
meta: Meta::List {
path: Path {
leading_colon: None,
segments: [
PathSegment {
ident: Ident {
ident: "default_value",
span: #0 bytes(10045..10058),
},
arguments: PathArguments::None,
},
],
},
delimiter: MacroDelimiter::Paren(
Paren,
),
tokens: TokenStream [
Ident {
ident: "false",
span: #0 bytes(10059..10064),
},
],
},
},
],
vis: Visibility::Public(
Pub,
),
mutability: FieldMutability::None,
ident: Some(
Ident {
ident: "show_stack_on_push",
span: #0 bytes(10075..10093),
},
),
colon_token: Some(
Colon,
),
ty: Type::Path {
qself: None,
path: Path {
leading_colon: None,
segments: [
PathSegment {
ident: Ident {
ident: "bool",
span: #0 bytes(10095..10099),
},
arguments: PathArguments::None,
},
],
},
},
},
Comma,
Field {
attrs: [
Attribute {
pound_token: Pound,
style: AttrStyle::Outer,
bracket_token: Bracket,
meta: Meta::Path {
leading_colon: None,
segments: [
PathSegment {
ident: Ident {
ident: "no_config",
span: #0 bytes(10107..10116),
},
arguments: PathArguments::None,
},
],
},
},
],
vis: Visibility::Public(
Pub,
),
mutability: FieldMutability::None,
ident: Some(
Ident {
ident: "show_stack_on_pop",
span: #0 bytes(10126..10143),
},
),
colon_token: Some(
Colon,
),
ty: Type::Path {
qself: None,
path: Path {
leading_colon: None,
segments: [
PathSegment {
ident: Ident {
ident: "bool",
span: #0 bytes(10145..10149),
},
arguments: PathArguments::None,
},
],
},
},
},
Comma,
Field {
attrs: [
Attribute {
pound_token: Pound,
style: AttrStyle::Outer,
bracket_token: Bracket,
meta: Meta::NameValue {
path: Path {
leading_colon: None,
segments: [
PathSegment {
ident: Ident {
ident: "default_value",
span: #0 bytes(10157..10170),
},
arguments: PathArguments::None,
},
],
},
eq_token: Eq,
value: Expr::Lit {
attrs: [],
lit: Lit::Bool {
value: false,
},
},
},
},
],
vis: Visibility::Public(
Pub,
),
mutability: FieldMutability::None,
ident: Some(
Ident {
ident: "show_books_on_bookmark",
span: #0 bytes(10188..10210),
},
),
colon_token: Some(
Colon,
),
ty: Type::Path {
qself: None,
path: Path {
leading_colon: None,
segments: [
PathSegment {
ident: Ident {
ident: "bool",
span: #0 bytes(10212..10216),
},
arguments: PathArguments::None,
},
],
},
},
},
Comma,
],
},
semi_token: None,
},
}