enum_tools/generator/
features.rs1use crate::feature::as_str_fn::{AsStrMode, FeatureAsStrFn};
2use crate::feature::debug_trait::FeatureDebugTrait;
3use crate::feature::display_trait::FeatureDisplayTrait;
4use crate::feature::from_str_fn::{FeatureFromStrFn, FromStrFnMode};
5use crate::feature::from_str_trait::{FeatureFromStrTrait, FromStrMode};
6use crate::feature::into_fn::FeatureIntoFn;
7use crate::feature::into_str_trait::FeatureIntoStrTrait;
8use crate::feature::into_trait::FeatureIntoTrait;
9use crate::feature::iter::{FeatureIter, IterMode};
10use crate::feature::max_const::FeatureMaxConst;
11use crate::feature::min_const::FeatureMinConst;
12use crate::feature::names::FeatureNames;
13use crate::feature::next_back_fn::FeatureNextBackFn;
14use crate::feature::next_fn::FeatureNextFn;
15use crate::feature::range_fn::FeatureRangeFn;
16use crate::feature::table_enum::FeatureTableEnum;
17use crate::feature::table_name::FeatureTableName;
18use crate::feature::table_range::FeatureTableRange;
19use crate::feature::try_from_fn::FeatureTryFromFn;
20use crate::feature::try_from_trait::FeatureTryFromTrait;
21use crate::generator::Derive;
22
23pub(crate) struct Features {
24 pub(crate) as_str_fn: FeatureAsStrFn,
25 pub(crate) debug_trait: FeatureDebugTrait,
26 pub(crate) display_trait: FeatureDisplayTrait,
27 pub(crate) from_str_fn: FeatureFromStrFn,
28 pub(crate) from_str_trait: FeatureFromStrTrait,
29 pub(crate) into_fn: FeatureIntoFn,
30 pub(crate) into_str_trait: FeatureIntoStrTrait,
31 pub(crate) into_trait: FeatureIntoTrait,
32 pub(crate) iter: FeatureIter,
33 pub(crate) max_const: FeatureMaxConst,
34 pub(crate) min_const: FeatureMinConst,
35 pub(crate) names: FeatureNames,
36 pub(crate) next_back_fn: FeatureNextBackFn,
37 pub(crate) next_fn: FeatureNextFn,
38 pub(crate) range_fn: FeatureRangeFn,
39 pub(crate) table_enum: FeatureTableEnum,
40 pub(crate) table_name: FeatureTableName,
41 pub(crate) table_range: FeatureTableRange,
42 pub(crate) try_from_fn: FeatureTryFromFn,
43 pub(crate) try_from_trait: FeatureTryFromTrait,
44}
45
46impl Features {
47 pub(crate) fn resolve(&mut self, derive: &Derive) {
48 self.resolve_enable(derive);
49 self.resolve_auto(derive);
50 self.resolve_enable(derive);
51 }
52
53 fn resolve_auto(&mut self, derive: &Derive) {
54 if [
55 self.as_str_fn.enabled && self.as_str_fn.mode == AsStrMode::Auto,
56 self.from_str_trait.enabled && self.from_str_trait.mode == FromStrMode::Auto,
57 self.from_str_fn.enabled && self.from_str_fn.mode == FromStrFnMode::Auto,
58 ]
59 .into_iter()
60 .filter(|b| *b)
61 .count()
62 > 1
63 {
64 self.table_name.enabled = true;
65 }
66
67 let table_enum = self.table_enum.enabled;
68 let table_name = self.table_name.enabled;
69
70 if self.as_str_fn.enabled && self.as_str_fn.mode == AsStrMode::Auto {
71 if table_name {
72 self.as_str_fn.mode = AsStrMode::Table;
73 } else {
74 self.as_str_fn.mode = AsStrMode::Match;
75 }
76 }
77
78 if self.from_str_trait.enabled && self.from_str_trait.mode == FromStrMode::Auto {
79 if table_name {
80 self.from_str_trait.mode = FromStrMode::Table;
81 } else {
82 self.from_str_trait.mode = FromStrMode::Match;
83 }
84 }
85
86 if self.from_str_fn.enabled && self.from_str_fn.mode == FromStrFnMode::Auto {
87 if table_name {
88 self.from_str_fn.mode = FromStrFnMode::Table;
89 } else {
90 self.from_str_fn.mode = FromStrFnMode::Match;
91 }
92 }
93
94 if self.iter.enabled && self.iter.mode == IterMode::Auto {
95 if derive.mode.is_gapless() {
96 self.iter.mode = IterMode::Range;
97 } else {
98 if table_enum {
100 self.iter.mode = IterMode::Table;
101 } else if derive.num_values * derive.repr_size_guessed <= 8
102 && !self.range_fn.enabled
103 {
104 self.iter.mode = IterMode::TableInline;
105 } else {
106 self.iter.mode = IterMode::NextAndBack;
107 }
108 }
109 }
110 }
111
112 fn resolve_enable(&mut self, derive: &Derive) {
113 let mut features2 = Features2 {
114 as_str_fn: &mut self.as_str_fn,
115 iter: &mut self.iter,
116 min_const: &mut self.min_const,
117 max_const: &mut self.max_const,
118 next_fn: &mut self.next_fn,
119 next_back_fn: &mut self.next_back_fn,
120 table_enum: &mut self.table_enum,
121 table_name: &mut self.table_name,
122 table_range: &mut self.table_range,
123 };
124 self.debug_trait.check(&mut features2);
125 self.display_trait.check(&mut features2);
126 self.into_str_trait.check(&mut features2);
127 self.range_fn.check(derive, &mut features2);
128
129 let mut features1 = Features1 {
130 min_const: features2.min_const,
131 max_const: features2.max_const,
132 next_fn: features2.next_fn,
133 next_back_fn: features2.next_back_fn,
134 table_enum: features2.table_enum,
135 table_name: features2.table_name,
136 table_range: features2.table_range,
137 };
138 features2.as_str_fn.check(derive, &mut features1);
139 self.from_str_trait.check(derive, &mut features1);
140 self.from_str_fn.check(derive, &mut features1);
141 features2.iter.check(derive, &mut features1);
142 self.names.check(&mut features1);
143
144 let mut features0 = Features0 {
145 min_const: features1.min_const,
146 max_const: features1.max_const,
147 table_range: features1.table_range,
148 };
149 features1.next_fn.check(&mut features0);
150 features1.next_back_fn.check(&mut features0);
151 self.try_from_trait.check(&mut features0);
152 self.try_from_fn.check(&mut features0);
153
154 self.into_trait.check();
156 self.into_fn.check();
157 features0.min_const.check();
158 features0.max_const.check();
159 features1.table_enum.check();
160 features1.table_name.check();
161 features0.table_range.check();
162 }
163}
164
165pub(crate) struct Features0<'a> {
166 pub(crate) max_const: &'a mut FeatureMaxConst,
167 pub(crate) min_const: &'a mut FeatureMinConst,
168 pub(crate) table_range: &'a mut FeatureTableRange,
169}
170
171pub(crate) struct Features1<'a> {
172 pub(crate) max_const: &'a mut FeatureMaxConst,
173 pub(crate) min_const: &'a mut FeatureMinConst,
174 pub(crate) next_fn: &'a mut FeatureNextFn,
175 pub(crate) next_back_fn: &'a mut FeatureNextBackFn,
176 pub(crate) table_enum: &'a mut FeatureTableEnum,
177 pub(crate) table_name: &'a mut FeatureTableName,
178 pub(crate) table_range: &'a mut FeatureTableRange,
179}
180
181pub(crate) struct Features2<'a> {
182 pub(crate) as_str_fn: &'a mut FeatureAsStrFn,
183 pub(crate) iter: &'a mut FeatureIter,
184 pub(crate) max_const: &'a mut FeatureMaxConst,
185 pub(crate) min_const: &'a mut FeatureMinConst,
186 pub(crate) next_fn: &'a mut FeatureNextFn,
187 pub(crate) next_back_fn: &'a mut FeatureNextBackFn,
188 pub(crate) table_enum: &'a mut FeatureTableEnum,
189 pub(crate) table_name: &'a mut FeatureTableName,
190 pub(crate) table_range: &'a mut FeatureTableRange,
191}