kefta_core/structs/
map.rs1use std::collections::BTreeMap;
2use crate::error::{KeftaError, KeftaResult};
3use crate::node::{AttrNode, AttrTree};
4use crate::parse::AttrValue;
5use crate::structs::AttrStruct;
6
7const _EMPTY: Vec<AttrNode> = Vec::new();
8const _EMPTY_REF: &Vec<AttrNode> = &_EMPTY;
9
10pub struct AttrMap {
12 map: BTreeMap<String, Vec<AttrNode>>
13}
14
15impl AttrMap {
16 pub fn new(nodes: Vec<AttrNode>) -> Self {
18 let mut map: BTreeMap<String, Vec<AttrNode>> = BTreeMap::new();
19
20 for node in nodes {
21 let name = node.ident.to_string();
22
23 if let Some(array) = map.get_mut(&name) {
24 array.push(node);
25 } else {
26 map.insert(name, vec![node]);
27 }
28 }
29
30 Self { map }
31 }
32
33 pub fn alias<'a>(&self, names: &[&'a str]) -> Option<&'a str> {
36 for name in names {
37 if self.map.contains_key(*name) {
38 return Some(name)
39 }
40 }
41 None
42 }
43
44 pub fn alias_otherwise<'a>(&self, names: &[&'a str]) -> &'a str {
47 for name in names {
48 if self.map.contains_key(*name) {
49 return name
50 }
51 }
52 names[0]
53 }
54
55 pub fn peek_nodes(&self, key: &str) -> &Vec<AttrNode> {
57 match self.map.get(key) {
58 None => &_EMPTY_REF,
59 Some(nodes) => &nodes
60 }
61 }
62
63 pub fn get_nodes(&mut self, key: &str) -> Option<Vec<AttrNode>> {
65 match self.map.remove(key) {
66 None => None,
67 Some(nodes) => Some(nodes)
68 }
69 }
70
71 pub fn peek_node(&self, key: &str) -> Option<&AttrNode> {
73 match self.map.get(key) {
74 None => None,
75 Some(nodes) => if nodes.len() == 1 {
76 nodes.first()
77 } else {
78 None
79 }
80 }
81 }
82
83 pub fn get_node(&mut self, key: &str, error: bool) -> KeftaResult<Option<AttrNode>> {
90 match self.map.remove(key) {
91 None => Ok(None),
92 Some(mut nodes) => if nodes.len() == 1 {
93 Ok(Some(nodes.remove(0)))
94 } else {
95 if error {
96 Err(KeftaError::Multiple {
97 key: key.to_string(),
98 count: nodes.len(),
99 span: nodes.first().unwrap().ident.span()
100 })
101 } else {
102 Ok(None)
103 }
104 }
105 }
106 }
107
108 pub fn gather_nodes(&mut self, keys: &[&str]) -> KeftaResult<Vec<AttrNode>> {
110 let mut build = Vec::new();
111
112 for key in keys {
113 if let Some(nodes) = self.get_nodes(key) {
114 for node in nodes {
115 build.push(node);
116 }
117 }
118 }
119
120 Ok(build)
121 }
122
123
124 pub fn parse_one<T: AttrValue + Default>(&mut self, keys: &[&str]) -> KeftaResult<T> {
129 for key in keys {
130 if let Some(node) = self.get_node(key, false)? {
131 return <T as AttrValue>::parse(node);
132 }
133 }
134 Ok(<T as Default>::default())
135 }
136
137 pub fn parse_optional<T: AttrValue>(&mut self, keys: &[&str]) -> KeftaResult<Option<T>> {
139 for key in keys {
140 if let Some(node) = self.get_node(key, false)? {
141 return <T as AttrValue>::parse(node).map(|x| Some(x));
142 }
143 }
144 Ok(None)
145 }
146
147 pub fn parse_required<T: AttrValue>(&mut self, keys: &[&str]) -> KeftaResult<T> {
150 for key in keys {
151 if let Some(node) = self.get_node(key, false)? {
152 return <T as AttrValue>::parse(node);
153 }
154 }
155 Err(KeftaError::Required {
156 key: keys[0].to_string(),
157 multiple: false
158 })
159 }
160
161 pub fn parse_array<T: AttrValue>(&mut self, keys: &[&str]) -> KeftaResult<Vec<T>> {
163 let mut build = Vec::new();
164
165 for key in keys {
166 if let Some(nodes) = self.get_nodes(key) {
167 for node in nodes {
168 build.push(T::parse(node)?);
169 }
170 }
171 }
172
173 Ok(build)
174 }
175
176 pub fn parse_array_optional<T: AttrValue>(&mut self, keys: &[&str]) -> KeftaResult<Option<Vec<T>>> {
179 let array = self.parse_array(&keys)?;
180 if array.is_empty() { Ok(None) } else { Ok(Some(array)) }
181 }
182
183 pub fn parse_array_required<T: AttrValue>(&mut self, keys: &[&str]) -> KeftaResult<Vec<T>> {
186 let array = self.parse_array(&keys)?;
187 if array.is_empty() {
188 Err(KeftaError::Required {
189 key: keys[0].to_string(),
190 multiple: true
191 })
192 } else {
193 Ok(array)
194 }
195 }
196
197 pub fn parse_container<T: AttrStruct>(&mut self, keys: &[&str]) -> KeftaResult<T> {
202 let mut build = Vec::new();
203
204 for node in self.gather_nodes(&keys)? {
205 match node.data {
206 AttrTree::Container { nodes, .. } => build.extend(nodes),
207 _ => return Err(KeftaError::ExpectedContainer { ident: node.ident })
208 }
209 }
210
211 T::parse(build)
212 }
213
214 pub fn parse_with<T>(&mut self, keys: &[&str], func: fn(nodes: Vec<AttrNode>) -> KeftaResult<T>) -> KeftaResult<T> {
216 (func)(self.gather_nodes(&keys)?)
217 }
218}