1use {Diagnostics, Loc, OptionEntry, RpNumber, WithSpan};
4
5pub trait Options {
7 type Item: OptionEntry;
8
9 fn items(&self) -> &Vec<Loc<Self::Item>>;
10
11 fn lookup(&self, name: &str) -> Vec<Loc<&Self::Item>> {
12 self.items()
13 .iter()
14 .filter(move |o| o.name() == name)
15 .map(|option| Loc::as_ref(&option))
16 .collect()
17 }
18
19 fn find_all_strings(&self, diag: &mut Diagnostics, name: &str) -> Result<Vec<Loc<String>>, ()> {
23 let mut out = Vec::new();
24
25 for s in self.lookup(name) {
26 let (value, span) = Loc::take_pair(s);
27 let string = value.as_string().with_span(diag, &span)?;
28 out.push(Loc::new(string, span));
29 }
30
31 Ok(out)
32 }
33
34 fn find_all_u32(&self, diag: &mut Diagnostics, name: &str) -> Result<Vec<Loc<RpNumber>>, ()> {
35 let mut out = Vec::new();
36
37 for s in self.lookup(name) {
38 let (value, span) = Loc::take_pair(s);
39 let number = value.as_number().with_span(diag, &span)?;
40 out.push(Loc::new(number, span));
41 }
42
43 Ok(out)
44 }
45
46 fn find_all_identifiers(
51 &self,
52 diag: &mut Diagnostics,
53 name: &str,
54 ) -> Result<Vec<Loc<String>>, ()> {
55 let mut out = Vec::new();
56
57 for s in self.lookup(name) {
58 let (value, span) = Loc::take_pair(s);
59 let identifier = value.as_identifier().with_span(diag, &span)?;
60 out.push(Loc::new(identifier, span));
61 }
62
63 Ok(out)
64 }
65
66 fn find_one_identifier(
71 &self,
72 diag: &mut Diagnostics,
73 name: &str,
74 ) -> Result<Option<Loc<String>>, ()> {
75 Ok(self.find_all_identifiers(diag, name)?.into_iter().next())
76 }
77
78 fn find_one_string(
79 &self,
80 diag: &mut Diagnostics,
81 name: &str,
82 ) -> Result<Option<Loc<String>>, ()> {
83 Ok(self.find_all_strings(diag, name)?.into_iter().next())
84 }
85
86 fn find_one_u32(
87 &self,
88 diag: &mut Diagnostics,
89 name: &str,
90 ) -> Result<Option<Loc<RpNumber>>, ()> {
91 Ok(self.find_all_u32(diag, name)?.into_iter().next())
92 }
93}
94
95impl<T> Options for Vec<Loc<T>>
96where
97 T: OptionEntry,
98{
99 type Item = T;
100
101 fn items(&self) -> &Vec<Loc<Self::Item>> {
102 self
103 }
104}