1use std::collections::btree_set::IntoIter;
63use std::collections::VecDeque;
64use std::fmt::Display;
65use std::{
66 collections::{BTreeSet, HashMap, HashSet},
67 hash::Hash,
68};
69
70#[derive(Clone, Debug, Eq, PartialEq, Hash)]
73pub enum ConfigType {
74 Bool,
75 Tristate,
76 String,
77 Int,
78 Hex,
79}
80
81impl Display for ConfigType {
83 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 match self {
85 ConfigType::Bool => f.write_str("bool"),
86 ConfigType::Tristate => f.write_str("tristate"),
87 ConfigType::String => f.write_str("string"),
88 ConfigType::Int => f.write_str("int"),
89 ConfigType::Hex => f.write_str("hex"),
90 }
91 }
92}
93
94#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
99pub enum Expr {
100 Sym(String), Eq(BTreeSet<Expr>),
103 Ne(BTreeSet<Expr>),
104 Lt(BTreeSet<Expr>),
105 Gt(BTreeSet<Expr>),
106 Lte(BTreeSet<Expr>),
107 Gte(BTreeSet<Expr>),
108 And(BTreeSet<Expr>),
109 Or(BTreeSet<Expr>),
110 Sub(Box<Expr>),
111 Not(Box<Expr>),
112}
113
114impl Expr {
115 pub fn is_sym(&self) -> bool {
116 match self {
117 Self::Sym(_) => true,
118 _ => false,
119 }
120 }
121
122 pub fn is_not(&self) -> bool {
123 match self {
124 Self::Not(_) => true,
125 _ => false,
126 }
127 }
128
129 pub fn is_sub(&self) -> bool {
130 match self {
131 Self::Sub(_) => true,
132 _ => false,
133 }
134 }
135
136 pub fn is_comparison(&self) -> bool {
137 match self {
138 Self::Eq(_)
139 | Self::Ne(_)
140 | Self::Lt(_)
141 | Self::Gt(_)
142 | Self::Lte(_)
143 | Self::Gte(_)
144 | Self::And(_)
145 | Self::Or(_) => true,
146 _ => false,
147 }
148 }
149
150 pub fn contains(&self, expr: &Expr) -> bool {
151 match self {
152 Self::Sym(_) => false,
153 Self::Sub(b) | Self::Not(b) => b.contains(expr),
154 Self::Eq(s)
155 | Self::Ne(s)
156 | Self::Lt(s)
157 | Self::Gt(s)
158 | Self::Lte(s)
159 | Self::Gte(s)
160 | Self::And(s)
161 | Self::Or(s) => s.contains(expr),
162 }
163 }
164
165 pub fn is_eq(&self) -> bool {
166 match self {
167 Self::Eq(_) => true,
168 _ => false,
169 }
170 }
171 pub fn is_ne(&self) -> bool {
172 match self {
173 Self::Ne(_) => true,
174 _ => false,
175 }
176 }
177 pub fn is_lt(&self) -> bool {
178 match self {
179 Self::Lt(_) => true,
180 _ => false,
181 }
182 }
183 pub fn is_gt(&self) -> bool {
184 match self {
185 Self::Gt(_) => true,
186 _ => false,
187 }
188 }
189 pub fn is_gte(&self) -> bool {
190 match self {
191 Self::Gte(_) => true,
192 _ => false,
193 }
194 }
195 pub fn is_lte(&self) -> bool {
196 match self {
197 Self::Lte(_) => true,
198 _ => false,
199 }
200 }
201 pub fn is_and(&self) -> bool {
202 match self {
203 Self::And(_) => true,
204 _ => false,
205 }
206 }
207 pub fn is_or(&self) -> bool {
208 match self {
209 Self::Or(_) => true,
210 _ => false,
211 }
212 }
213
214 pub fn get_sym(&self) -> Option<String> {
215 match self {
216 Self::Sym(s) => Some(s.to_string()),
217 _ => None,
218 }
219 }
220
221 pub fn get_not_expr(&self) -> Option<Expr> {
222 match self {
223 Self::Not(e) => Some(e.as_ref().clone()),
224 _ => None,
225 }
226 }
227
228 pub fn get_sub_expr(&self) -> Option<Expr> {
229 match self {
230 Self::Sub(e) => Some(e.as_ref().clone()),
231 _ => None,
232 }
233 }
234
235 pub fn len(&self) -> usize {
236 match self {
237 Self::Eq(s)
238 | Self::Ne(s)
239 | Self::Lt(s)
240 | Self::Gt(s)
241 | Self::Lte(s)
242 | Self::Gte(s)
243 | Self::And(s)
244 | Self::Or(s) => s.len(),
245 _ => 1,
246 }
247 }
248}
249
250impl IntoIterator for Expr {
251 type Item = Expr;
252 type IntoIter = IntoIter<Self::Item>;
253 fn into_iter(self) -> Self::IntoIter {
254 match self {
255 Self::Eq(s)
256 | Self::Ne(s)
257 | Self::Lt(s)
258 | Self::Gt(s)
259 | Self::Lte(s)
260 | Self::Gte(s)
261 | Self::And(s)
262 | Self::Or(s) => s.into_iter(),
263 Self::Sym(s) => {
264 let mut set = BTreeSet::new();
265 set.insert(Expr::Sym(s.to_string()));
266 set.into_iter()
267 }
268 Self::Sub(s) | Self::Not(s) => {
269 let mut set = BTreeSet::new();
270 set.insert(*s.clone());
271 set.into_iter()
272 }
273 }
274 }
275}
276
277#[derive(Clone, Debug, Eq, PartialEq, Hash)]
280pub struct Dependency {
281 expr: Expr,
282}
283
284impl Dependency {
285 pub fn expr(&self) -> Expr {
286 self.expr.clone()
287 }
288
289 pub fn new(expr: &Expr) -> Self {
290 Dependency { expr: expr.clone() }
291 }
292
293 pub fn len(&self) -> usize {
294 return self.expr.len();
295 }
296
297 pub fn contains(&self, expr: &Expr) -> bool {
298 self.expr.contains(expr)
299 }
300}
301
302#[derive(Clone, Debug, Eq, PartialEq)]
304pub struct ConfigTypeInstance {
305 config_type: ConfigType,
306 dependency: Dependency,
307}
308
309#[derive(Clone, Debug, Eq, PartialEq)]
312pub struct Range {
313 pub(super) lhs: i64,
314 pub(super) rhs: i64,
315 pub(super) dependency: Option<Dependency>,
316}
317
318impl Range {
319 pub fn lhs(&self) -> i64 {
320 self.lhs
321 }
322 pub fn rhs(&self) -> i64 {
323 self.rhs
324 }
325 pub fn dependency(&self) -> &Option<Dependency> {
326 &self.dependency
327 }
328}
329
330#[derive(Clone, Debug, Eq, PartialEq)]
333pub struct Config {
334 pub(super) name: String,
335 pub(super) prompt: Option<String>,
336 pub(super) types: HashMap<ConfigType, Option<Dependency>>,
337 pub(super) defaults: HashMap<Expr, Option<Dependency>>,
338 pub(super) dependencies: HashSet<Dependency>,
339 pub(super) reverse_dependencies: HashMap<String, Option<Dependency>>,
340 pub(super) weak_dependencies: HashMap<String, Option<Dependency>>,
341 pub(super) menu_dependencies: HashSet<Dependency>,
342 pub(super) range: Option<Range>,
343 pub(super) help: VecDeque<String>,
344}
345
346impl Config {
347 pub fn create(name: &str) -> Self {
348 Self {
349 name: name.to_string(),
350 prompt: None,
351 types: HashMap::new(),
352 defaults: HashMap::new(),
353 dependencies: HashSet::new(),
354 reverse_dependencies: HashMap::new(),
355 weak_dependencies: HashMap::new(),
356 menu_dependencies: HashSet::new(),
357 range: None,
358 help: VecDeque::new(),
359 }
360 }
361}