started default function
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user