1use crate::{AsIter, Value};
2
3pub trait Argument<const CONST: bool> {
4 type Value: Value<CONST>;
5
6 fn name(&self) -> &str;
7 fn value(&self) -> &Self::Value;
8}
9
10pub trait ConstArgument: Argument<true> {}
11pub trait VariableArgument: Argument<false> {}
12
13impl<T: Argument<true>> ConstArgument for T {}
14impl<T: Argument<false>> VariableArgument for T {}
15
16pub trait Arguments<const CONST: bool>: AsIter<Item = Self::Argument> {
17 type Argument: Argument<CONST>;
18
19 fn equivalent(optional_self: Option<&Self>, optional_other: Option<&Self>) -> bool {
20 match (optional_self, optional_other) {
21 (None, None) => true,
22 (None, Some(other)) => other.is_empty(),
23 (Some(s), None) => s.is_empty(),
24 (Some(s), Some(other)) => {
25 let s_count = s.len();
27 let o_count = other.len();
28 if s_count != o_count {
29 return false;
30 }
31 s.iter().all(|s_arg| {
33 other.iter().any(|o_arg| {
34 s_arg.name() == o_arg.name()
35 && s_arg.value().as_ref() == o_arg.value().as_ref()
36 })
37 })
38 }
39 }
40 }
41}
42
43pub trait ConstArguments: Arguments<true> {}
44pub trait VariableArguments: Arguments<false> {}
45
46impl<T: Arguments<true>> ConstArguments for T {}
47impl<T: Arguments<false>> VariableArguments for T {}