utility_macros_internals/derive/
field_attributes.rs

1use convert_case::{Case, Casing};
2use proc_macro2::TokenTree;
3use syn::{Field, Ident, Meta};
4
5pub struct FieldAttributesContext {
6    pub helper: &'static str,
7    pub rename_all: Option<Case>,
8}
9
10pub struct FieldAttributesData {
11    pub ident: Ident,
12    pub skip: bool,
13}
14
15pub fn field_attributes(
16    FieldAttributesContext { helper, rename_all }: &FieldAttributesContext,
17    field: &Field,
18) -> FieldAttributesData {
19    let mut field_ident = field.ident.clone().expect("Field must have an identifier");
20    let mut skip = false;
21
22    for attr in &field.attrs {
23        let Meta::List(meta) = &attr.meta else {
24            continue;
25        };
26
27        if !meta
28            .path
29            .segments
30            .first()
31            .map_or(false, |seg| seg.ident == helper)
32        {
33            continue;
34        }
35
36        let mut tokens = meta.clone().tokens.into_iter().peekable();
37        while let Some(token) = tokens.next() {
38            let TokenTree::Ident(ident) = token else {
39                continue;
40            };
41
42            if ident == "name" {
43                let Some(TokenTree::Punct(punct)) = tokens.next() else {
44                    panic!("Expected punct")
45                };
46
47                if punct.as_char() != '=' {
48                    panic!("Expected '='")
49                }
50
51                let Some(TokenTree::Ident(ident)) = tokens.next() else {
52                    panic!("Expected ident")
53                };
54
55                field_ident = ident;
56            } else if let Some(case) = rename_all {
57                let string = ident.to_string().to_case(case.clone());
58                field_ident = Ident::new(string.as_str(), ident.span());
59            }
60
61            if ident == "skip" {
62                skip = true;
63            }
64        }
65    }
66
67    FieldAttributesData {
68        ident: field_ident,
69        skip,
70    }
71}