Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_jdat/src/map.rs

13.6 KiB, 54 runs

created by r1870400018:477, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use crate::prelude::*;
2
3use oxedyne_fe2o3_core::{
4 prelude::*,
5 byte::ToBytes,
6};
7
8use std::{
9 collections::BTreeMap,
10};
11
12
13pub type DaticleMap = BTreeMap<Dat, Dat>;
14pub type OrdDaticleMap = BTreeMap<MapKey, Dat>;
15
16pub fn create_dat_map(kv: Vec<(Dat, Dat)>) -> Dat {
17 let mut map = DaticleMap::new();
18 for (k, v) in kv {
19 map.insert(k, v);
20 }
21 Dat::Map(map)
22}
23
24pub fn create_dat_ordmap(kv: Vec<(Dat, Dat)>) -> Dat {
25 let mut map = OrdDaticleMap::new();
26 let mut i: u64 = Dat::OMAP_ORDER_START_DEFAULT;
27 for (k, v) in kv {
28 map.insert(MapKey::new(i, k), v);
29 i += Dat::OMAP_ORDER_DELTA_DEFAULT;
30 }
31 Dat::OrdMap(map)
32}
33
34#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
35pub struct MapKey {
36 ord: u64,
37 dat: Dat,
38}
39
40impl ToBytes for MapKey {
41 fn to_bytes(&self, mut buf: Vec<u8>) -> Outcome<Vec<u8>> {
42 let mut buf2 = Vec::new();
43 buf2 = res!(self.dat.to_bytes(buf2));
44 buf.extend_from_slice(&buf2);
45 Ok(buf)
46 }
47}
48
49impl MapKey {
50 pub fn new(ord: u64, dat: Dat) -> Self {
51 Self {
52 ord,
53 dat,
54 }
55 }
56 pub fn ord(&self) -> u64 { self.ord }
57 pub fn dat(&self) -> &Dat { &self.dat }
58 pub fn into_dat(self) -> Dat { self.dat }
59}
60
61impl Dat {
62
63 /// Find the key in the map and return a reference to the value. If the map is an
64 /// `Dat::OrdMap`, check that the key is not represented in multiple `MapKey`s.
65 pub fn map_get(&self, key: &Self) -> Outcome<Option<&Self>> {
66 match self {
67 Dat::OrdMap(m) => {
68 let entries: Vec<(_, _)> = m
69 .iter()
70 .filter(|(mk, _)| mk.dat() == key)
71 .collect();
72 if entries.len() > 1 {
73 Err(err!(
74 "There are {} entries, {:?} with the same given daticle \
75 {:?} in the MapKey, which is not allowed.",
76 entries.len(), entries, key;
77 Invalid, Input, Exists))
78 } else if entries.len() == 0 {
79 Ok(None)
80 } else {
81 Ok(Some(entries[0].1))
82 }
83
84 },
85 Dat::Map(m) => Ok(m.get(key)),
86 _ => Ok(None),
87 }
88 }
89
90 /// Find the key in the map and remove and return the value. If the map is an
91 /// `Dat::OrdMap`, check that the key is not represented in multiple `MapKey`s.
92 pub fn map_remove(&mut self, key: &Self) -> Outcome<Option<Self>> {
93 match self {
94 Dat::OrdMap(m) => {
95 let entries: Vec<(_, _)> = m
96 .iter()
97 .filter(|(mk, _)| mk.dat() == key)
98 .collect();
99 if entries.len() > 1 {
100 Err(err!(
101 "There are {} entries, {:?} with the same given daticle \
102 {:?} in the MapKey, which is not allowed.",
103 entries.len(), entries, key;
104 Invalid, Input, Exists))
105 } else if entries.len() == 0 {
106 Ok(None)
107 } else {
108 Ok(m.remove(&entries[0].0.clone()))
109 }
110
111 },
112 Dat::Map(m) => Ok(m.remove(key)),
113 _ => Ok(None),
114 }
115 }
116
117 /// Raise an error if the dat is not a map or the key is not present, otherwise return a
118 /// reference to the associated value.
119 pub fn map_get_must(&self, key: &Self) -> Outcome<&Self> {
120 match res!(self.map_get(key)) {
121 Some(dat) => Ok(dat),
122 None => Err(err!(
123 "The key {:?} does not map to any value, as expected.", key;
124 Input, Missing)),
125 }
126 }
127
128 pub fn map_get_string(&self, key: &Self) -> Outcome<String> {
129 let val = res!(self.map_get_must(key));
130 match val.get_string() {
131 Some(s) => Ok(s),
132 None => Err(err!(
133 "The key {:?} maps to a value of kind {:?}, \
134 expected a string.", key, val.kind();
135 Input, Mismatch)),
136 }
137 }
138
139 pub fn map_get_i64(&self, key: &Self) -> Outcome<i64> {
140 let val = res!(self.map_get_must(key));
141 match val.get_i64() {
142 Some(n) => Ok(n),
143 None => Err(err!(
144 "The key {:?} maps to a value of kind {:?}, \
145 expected an integer.", key, val.kind();
146 Input, Mismatch)),
147 }
148 }
149
150 pub fn map_get_u64(&self, key: &Self) -> Outcome<u64> {
151 let val = res!(self.map_get_must(key));
152 match val.get_u64() {
153 Some(n) => Ok(n),
154 None => Err(err!(
155 "The key {:?} maps to a value of kind {:?}, \
156 expected a non-negative integer.", key, val.kind();
157 Input, Mismatch)),
158 }
159 }
160
161 pub fn map_get_f64(&self, key: &Self) -> Outcome<f64> {
162 let val = res!(self.map_get_must(key));
163 match val.get_float64() {
164 Some(f) => Ok(f.0),
165 None => Err(err!(
166 "The key {:?} maps to a value of kind {:?}, \
167 expected a number.", key, val.kind();
168 Input, Mismatch)),
169 }
170 }
171
172 pub fn map_get_map(&self, key: &Self) -> Outcome<&Self> {
173 let val = res!(self.map_get_must(key));
174 match val {
175 Dat::Map(_) | Dat::OrdMap(_) => Ok(val),
176 _ => Err(err!(
177 "The key {:?} maps to a value of kind {:?}, \
178 expected a map.", key, val.kind();
179 Input, Mismatch)),
180 }
181 }
182
183 pub fn map_get_list(&self, key: &Self) -> Outcome<&Vec<Dat>> {
184 let val = res!(self.map_get_must(key));
185 match val {
186 Dat::List(v) | Dat::Vek(Vek(v)) => Ok(v),
187 _ => Err(err!(
188 "The key {:?} maps to a value of kind {:?}, \
189 expected a list.", key, val.kind();
190 Input, Mismatch)),
191 }
192 }
193
194 pub fn map_put(&mut self, key: Self, val: Self) -> Outcome<Option<Self>> {
195 match self {
196 Dat::Map(m) => Ok(m.insert(key, val)),
197 Dat::OrdMap(m) => {
198 // Find an existing entry with a matching dat key.
199 // Collect the matching MapKeys first so we can
200 // mutate the map afterwards without aliasing.
201 let existing: Vec<MapKey> = m
202 .iter()
203 .filter(|(mk, _)| mk.dat() == &key)
204 .map(|(mk, _)| mk.clone())
205 .collect();
206 if existing.len() > 1 {
207 return Err(err!(
208 "There are {} entries with the same key {:?} \
209 in the OrdMap, which is not allowed.",
210 existing.len(), key;
211 Invalid, Input, Exists));
212 }
213 if let Some(mk) = existing.into_iter().next() {
214 // Replace in place, preserving `ord`.
215 let prev = m.remove(&mk);
216 m.insert(mk, val);
217 Ok(prev)
218 } else {
219 // Append with the next available order slot.
220 let next_ord = m
221 .keys()
222 .map(|mk| mk.ord())
223 .max()
224 .map(|n| n + Dat::OMAP_ORDER_DELTA_DEFAULT)
225 .unwrap_or(Dat::OMAP_ORDER_START_DEFAULT);
226 m.insert(MapKey::new(next_ord, key), val);
227 Ok(None)
228 }
229 },
230 _ => Err(err!(
231 "Expected a Dat::Map or Dat::OrdMap, got {:?}.",
232 self.kind();
233 Input, Invalid, Mismatch)),
234 }
235 }
236
237 /// Raise an error if the dat is not a map or the key is not present, otherwise return
238 /// the removed value.
239 pub fn map_remove_must(&mut self, key: &Self) -> Outcome<Self> {
240 match res!(self.map_remove(key)) {
241 Some(dat) => Ok(dat),
242 None => Err(err!(
243 "The key {:?} does not map to any value, as expected.", key;
244 Input, Missing)),
245 }
246 }
247
248 /// Get a reference to the `Dat` specified by the key from a `Dat::Map`. The `Dat`
249 /// must be of one of a `Kind` in the given list.
250 pub fn map_get_type<'a>(
251 &self,
252 key: &'a Self,
253 kinds: &[&Kind],
254 )
255 -> Outcome<Option<&Self>>
256 {
257 match self.map_get(key) {
258 Ok(opt_val) => match opt_val {
259 Some(val) => {
260 for kind in kinds {
261 if &val.kind() == *kind {
262 return Ok(Some(val));
263 }
264 }
265 Err(err!(
266 "The key {} maps to a value of kind {:?}, \
267 which does not correspond with any of {:?}.",
268 key, val.kind(), kinds;
269 Input, Mismatch))
270 },
271 None => Ok(None),
272 },
273 Err(e) => Err(e),
274 }
275 }
276
277 /// Get a reference to the `Dat` specified by the key from a `Dat::Map`. The `Dat` must be of
278 /// one of a `Kind` in the given list. If none is present, an error is returned.
279 pub fn map_get_type_must<'a>(
280 &self,
281 key: &'a Self,
282 kinds: &[&Kind],
283 )
284 -> Outcome<&Self>
285 {
286 match self.map_get(key) {
287 Ok(opt_val) => match opt_val {
288 Some(val) => {
289 for kind in kinds {
290 if &val.kind() == *kind {
291 return Ok(val);
292 }
293 }
294 Err(err!(
295 "The key {} maps to a value of kind {:?}, \
296 which does not correspond with any of {:?}.",
297 key, val.kind(), kinds;
298 Input, Mismatch))
299 },
300 None => Err(err!(
301 "The key {:?} does not map to any value, as expected.", key;
302 Input, Missing)),
303 },
304 Err(e) => Err(e),
305 }
306 }
307
308 /// Remove the `Dat` specified by the key from a `Dat::Map`. The `Dat` must
309 /// be of one of the `Kind`s given.
310 pub fn map_remove_type(&mut self, key: &Self, kinds: &[&Kind]) -> Outcome<Self> {
311 if let Dat::Map(m) = self {
312 if let Some(d) = m.remove(key) {
313 for kind in kinds {
314 if &d.kind() == *kind {
315 return Ok(d);
316 }
317 }
318 return Err(err!(
319 "The key {} maps to a value of kind {:?}, \
320 which does not correspond with any of {:?}.",
321 key, d.kind(), kinds;
322 Input, Mismatch));
323 } else {
324 return Err(err!(
325 "The key {} does not map to any value, as \
326 required.",
327 key;
328 Input, Missing));
329 }
330 } else {
331 return Err(err!(
332 "Dat {} must be a map.",
333 self;
334 Input, Mismatch));
335 }
336 }
337
338 pub fn find(&self, keys: &Self) -> Outcome<Option<&Self>> {
339 match (self, keys) {
340 (Dat::Map(_m), Dat::List(keys)) => {
341 let mut current = self;
342 for key in keys {
343 match current {
344 Dat::Map(m) => {
345 current = match m.get(key) {
346 Some(v) => v,
347 None => return Ok(None),
348 };
349 }
350 _ => return Ok(None),
351 }
352 }
353 Ok(Some(current))
354 }
355 (Dat::OrdMap(_m), Dat::List(keys)) => {
356 let mut current = self;
357 for key in keys {
358 match current {
359 Dat::OrdMap(m) => {
360 current = match m.iter().find(|(k, _)| k.dat() == key) {
361 Some((_, v)) => v,
362 None => return Ok(None),
363 };
364 }
365 _ => return Ok(None),
366 }
367 }
368 Ok(Some(current))
369 }
370 (Dat::Map(_) | Dat::OrdMap(_), _) => Err(err!(
371 "Expected a Dat::List argument.";
372 Input, Invalid, Mismatch)),
373 _ => Err(err!(
374 "This method requires a map kind (Dat::Map or Dat::OrdMap).";
375 Input, Invalid, Mismatch)),
376 }
377 }
378
379 pub fn find_all<D: AsRef<Dat>>(&self, key: D) -> Outcome<Vec<&Self>> {
380 let key = key.as_ref();
381 let mut values = Vec::new();
382
383 match self {
384 Dat::Map(m) => {
385 for (k, v) in m.iter() {
386 if k == key {
387 values.push(v);
388 }
389 if let Dat::Map(_) | Dat::OrdMap(_) = v {
390 values.extend(res!(v.find_all(key)));
391 }
392 }
393 }
394 Dat::OrdMap(m) => {
395 for (k, v) in m.iter() {
396 if k.dat() == key {
397 values.push(v);
398 }
399 if let Dat::Map(_) | Dat::OrdMap(_) = v {
400 values.extend(res!(v.find_all(key)));
401 }
402 }
403 }
404 _ => (),
405 }
406
407 Ok(values)
408 }
409}