|
| 1 | +use crate::filter_ext::FilterExt; |
1 | 2 | use itertools::Itertools; |
2 | 3 | use proc_macro2::TokenStream; |
3 | 4 | use quote::quote; |
4 | 5 | use syn::spanned::Spanned; |
5 | 6 | use syn::{parse_str, Fields, Ident, Lit, Meta, NestedMeta, Path, Result}; |
6 | 7 | use synstructure::{decl_derive, AddBounds, BindingInfo, Structure, VariantInfo}; |
7 | 8 |
|
| 9 | +mod filter_ext; |
8 | 10 | #[cfg(test)] |
9 | 11 | mod tests; |
10 | 12 |
|
11 | 13 | decl_derive!([Debug, attributes(debug)] => custom_debug_derive); |
12 | 14 |
|
13 | 15 | fn custom_debug_derive(mut structure: Structure) -> Result<TokenStream> { |
| 16 | + filter_out_skipped_fields(&mut structure)?; |
| 17 | + |
14 | 18 | structure.add_bounds(AddBounds::Fields); |
15 | 19 |
|
16 | | - let skip_ident: Ident = parse_str("skip").unwrap(); |
| 20 | + let match_arms = |
| 21 | + structure.each_variant(|variant| generate_match_arm_body(variant).into_stream()); |
| 22 | + |
| 23 | + Ok(structure.gen_impl(quote! { |
| 24 | + gen impl ::core::fmt::Debug for @Self { |
| 25 | + fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { |
| 26 | + match self { |
| 27 | + #match_arms |
| 28 | + } |
| 29 | + } |
| 30 | + } |
| 31 | + })) |
| 32 | +} |
17 | 33 |
|
18 | | - let mut filter_err = None; |
| 34 | +fn filter_out_skipped_fields(structure: &mut Structure) -> Result<()> { |
| 35 | + let skip_ident: Ident = parse_str("skip").unwrap(); |
19 | 36 |
|
20 | | - structure.filter(|binding| { |
| 37 | + structure.try_filter(|binding| { |
21 | 38 | for meta in get_metas(binding) { |
22 | | - let meta = match meta { |
23 | | - Ok(meta) => meta, |
24 | | - Err(err) => { |
25 | | - filter_err = Some(err); |
26 | | - return false; |
27 | | - } |
28 | | - }; |
| 39 | + let meta = meta?; |
29 | 40 |
|
30 | 41 | if let NestedMeta::Meta(Meta::Path(ref path)) = meta { |
31 | 42 | if path |
32 | 43 | .get_ident() |
33 | 44 | .map(|ident| ident == &skip_ident) |
34 | 45 | .unwrap_or(false) |
35 | 46 | { |
36 | | - return false; |
| 47 | + return Ok(false); |
37 | 48 | } |
38 | 49 | } |
39 | 50 | } |
40 | 51 |
|
41 | | - true |
42 | | - }); |
43 | | - |
44 | | - if let Some(filter_err) = filter_err { |
45 | | - return Err(filter_err); |
46 | | - } |
47 | | - |
48 | | - let match_arms = |
49 | | - structure.each_variant(|variant| generate_match_arm_body(variant).into_stream()); |
| 52 | + Ok(true) |
| 53 | + })?; |
50 | 54 |
|
51 | | - Ok(structure.gen_impl(quote! { |
52 | | - gen impl ::core::fmt::Debug for @Self { |
53 | | - fn fmt(&self, fmt: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { |
54 | | - match self { |
55 | | - #match_arms |
56 | | - } |
57 | | - } |
58 | | - } |
59 | | - })) |
| 55 | + Ok(()) |
60 | 56 | } |
61 | 57 |
|
62 | 58 | fn generate_match_arm_body(variant: &VariantInfo) -> Result<TokenStream> { |
|
0 commit comments