Skip to content

Commit 30fa2ce

Browse files
committed
allow customizing fold and visit
1 parent 5fef720 commit 30fa2ce

File tree

2 files changed

+44
-39
lines changed

2 files changed

+44
-39
lines changed

crates/formality-macros/src/custom.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ pub(crate) struct Customize {
55
pub parse: bool,
66
pub debug: bool,
77
pub constructors: bool,
8+
pub fold: bool,
9+
pub visit: bool,
810
}
911

1012
impl syn::parse::Parse for Customize {
@@ -13,35 +15,36 @@ impl syn::parse::Parse for Customize {
1315

1416
let token_stream: TokenStream = input.parse()?;
1517
let mut tokens = token_stream.into_iter();
16-
while let Some(token) = tokens.next() {
17-
match token {
18-
proc_macro2::TokenTree::Ident(ident) if ident == "parse" => {
19-
if result.parse {
20-
return Err(syn::Error::new(ident.span(), "already customizing parse"));
21-
}
22-
result.parse = true;
23-
}
2418

25-
proc_macro2::TokenTree::Ident(ident) if ident == "debug" => {
26-
if result.debug {
27-
return Err(syn::Error::new(ident.span(), "already customizing debug"));
28-
}
29-
result.debug = true;
30-
}
19+
while let Some(token) = tokens.next() {
20+
macro_rules! match_customization_field_or_error {
21+
($($ident:ident,)*) => {
22+
match token {
23+
$(
24+
proc_macro2::TokenTree::Ident(ident) if ident == stringify!($ident) => {
25+
if result.$ident {
26+
return Err(syn::Error::new(ident.span(), &format!("already customizing {}", stringify!($ident))));
27+
}
28+
result.$ident = true;
29+
}
30+
)*
3131

32-
proc_macro2::TokenTree::Ident(ident) if ident == "constructors" => {
33-
if result.constructors {
34-
return Err(syn::Error::new(ident.span(), "already customizing debug"));
32+
_ => {
33+
return Err(syn::Error::new(
34+
token.span(),
35+
"unexpected token in customization",
36+
));
37+
}
3538
}
36-
result.constructors = true;
37-
}
39+
};
40+
}
3841

39-
_ => {
40-
return Err(syn::Error::new(
41-
token.span(),
42-
"unexpected token in customization",
43-
));
44-
}
42+
match_customization_field_or_error! {
43+
parse,
44+
debug,
45+
constructors,
46+
fold,
47+
visit,
4548
}
4649

4750
if let Some(token) = tokens.next() {

crates/formality-macros/src/term.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,33 @@ use crate::{
1515

1616
pub fn term(spec: Option<FormalitySpec>, mut input: DeriveInput) -> syn::Result<TokenStream> {
1717
let customize = attrs::customize(&input.attrs)?;
18-
let fold_impl = derive_fold(synstructure::Structure::new(&input));
19-
let visit_impl = derive_visit(synstructure::Structure::new(&input));
18+
let fold_impl = if customize.fold {
19+
Default::default()
20+
} else {
21+
derive_fold(synstructure::Structure::new(&input))
22+
};
23+
let visit_impl = if customize.visit {
24+
Default::default()
25+
} else {
26+
derive_visit(synstructure::Structure::new(&input))
27+
};
2028
let parse_impl = if customize.parse {
21-
None
29+
Default::default()
2230
} else {
23-
Some(derive_parse_with_spec(
24-
synstructure::Structure::new(&input),
25-
spec.as_ref(),
26-
)?)
31+
derive_parse_with_spec(synstructure::Structure::new(&input), spec.as_ref())?
2732
};
2833
let debug_impl = if customize.debug {
29-
None
34+
Default::default()
3035
} else {
31-
Some(derive_debug_with_spec(
32-
synstructure::Structure::new(&input),
33-
spec.as_ref(),
34-
))
36+
derive_debug_with_spec(synstructure::Structure::new(&input), spec.as_ref())
3537
};
3638
let term_impl = derive_term(synstructure::Structure::new(&input));
3739
let downcast_impls = downcast_impls(synstructure::Structure::new(&input));
3840
let upcast_impls = upcast_impls(synstructure::Structure::new(&input));
3941
let constructors = if customize.constructors {
40-
None
42+
Default::default()
4143
} else {
42-
Some(constructor_methods(synstructure::Structure::new(&input)))
44+
constructor_methods(synstructure::Structure::new(&input))
4345
};
4446
remove_formality_attributes(&mut input);
4547

0 commit comments

Comments
 (0)