educe/trait_handlers/deref/models/
field_attribute.rs1use quote::ToTokens;
2use syn::{Attribute, Meta, NestedMeta};
3
4use crate::{panic, Trait};
5
6#[derive(Clone)]
7pub struct FieldAttribute {
8 pub flag: bool,
9}
10
11#[derive(Debug, Clone)]
12pub struct FieldAttributeBuilder {
13 pub enable_flag: bool,
14}
15
16impl FieldAttributeBuilder {
17 #[allow(clippy::wrong_self_convention)]
18 pub fn from_deref_meta(&self, meta: &Meta) -> FieldAttribute {
19 let flag;
20
21 let correct_usage_for_deref_attribute = {
22 let mut usage = vec![];
23
24 if self.enable_flag {
25 usage.push(stringify!(#[educe(Deref)]));
26 }
27
28 usage
29 };
30
31 match meta {
32 Meta::List(_) => {
33 panic::attribute_incorrect_format("Deref", &correct_usage_for_deref_attribute)
34 },
35 Meta::NameValue(_) => {
36 panic::attribute_incorrect_format("Deref", &correct_usage_for_deref_attribute)
37 },
38 Meta::Path(_) => {
39 if !self.enable_flag {
40 panic::attribute_incorrect_format("Deref", &correct_usage_for_deref_attribute);
41 }
42
43 flag = true;
44 },
45 }
46
47 FieldAttribute {
48 flag,
49 }
50 }
51
52 #[allow(clippy::wrong_self_convention)]
53 pub fn from_attributes(self, attributes: &[Attribute], traits: &[Trait]) -> FieldAttribute {
54 let mut result = None;
55
56 for attribute in attributes.iter() {
57 if attribute.path.is_ident("educe") {
58 let meta = attribute.parse_meta().unwrap();
59
60 match meta {
61 Meta::List(list) => {
62 for p in list.nested.iter() {
63 match p {
64 NestedMeta::Meta(meta) => {
65 let meta_name = meta.path().into_token_stream().to_string();
66
67 let t = Trait::from_str(meta_name);
68
69 if traits.binary_search(&t).is_err() {
70 panic::trait_not_used(t);
71 }
72
73 if t == Trait::Deref {
74 if result.is_some() {
75 panic::reuse_a_trait(t);
76 }
77
78 result = Some(self.from_deref_meta(meta));
79 }
80 },
81 _ => panic::educe_format_incorrect(),
82 }
83 }
84 },
85 _ => panic::educe_format_incorrect(),
86 }
87 }
88 }
89
90 result.unwrap_or(FieldAttribute {
91 flag: false
92 })
93 }
94}