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 {
|
pub fn gen_config_assignments(fields: &Punctuated<Field, Comma>, config_map_name: &syn::Ident) -> TokenStream {
|
||||||
let mut assignments : TokenStream = TokenStream::new();
|
let mut assignments : TokenStream = TokenStream::new();
|
||||||
'fields: for field in fields.iter() {
|
'fields: for field in fields.iter() {
|
||||||
@@ -127,3 +164,7 @@ pub fn gen_config_assignments(fields: &Punctuated<Field, Comma>, config_map_name
|
|||||||
assignments
|
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
|
/// which parses a string and fills the fills recognised values into the struct
|
||||||
/// - implements `write_default_config() -> Result<String>`
|
/// - implements `write_default_config() -> Result<String>`
|
||||||
/// which write a default configuration, in case the documentation is lacking
|
/// 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 {
|
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
let name = &ast.ident;
|
let name = &ast.ident;
|
||||||
@@ -21,6 +21,9 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||||||
} else {
|
} else {
|
||||||
panic!("the macro `ConfigParser` applies only to structs!");
|
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 assignments: TokenStream = gen_config_assignments(fields, &config_name);
|
||||||
let func_parse_string: TokenStream = gen_parse_from_string(&config_name, &assignments);
|
let func_parse_string: TokenStream = gen_parse_from_string(&config_name, &assignments);
|
||||||
let func_parse_map: TokenStream = gen_parse_from_map(&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)]
|
#[derive(Debug, Clone, Default, ConfigParser)]
|
||||||
pub struct GeneralSettings {
|
pub struct GeneralSettings {
|
||||||
|
#[default_value(false)]
|
||||||
pub show_stack_on_push: bool,
|
pub show_stack_on_push: bool,
|
||||||
|
#[no_config]
|
||||||
pub show_stack_on_pop: bool,
|
pub show_stack_on_pop: bool,
|
||||||
|
#[default_value = false]
|
||||||
pub show_books_on_bookmark: bool,
|
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