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
| 1 | use crate::prelude::*; |
| 2 | |
| 3 | use oxedyne_fe2o3_core::{ |
| 4 | prelude::*, |
| 5 | byte::ToBytes, |
| 6 | }; |
| 7 | |
| 8 | use std::{ |
| 9 | collections::BTreeMap, |
| 10 | }; |
| 11 | |
| 12 | |
| 13 | pub type DaticleMap = BTreeMap<Dat, Dat>; |
| 14 | pub type OrdDaticleMap = BTreeMap<MapKey, Dat>; |
| 15 | |
| 16 | pub 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 | |
| 24 | pub 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)] |
| 35 | pub struct MapKey { |
| 36 | ord: u64, |
| 37 | dat: Dat, |
| 38 | } |
| 39 | |
| 40 | impl 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 | |
| 49 | impl 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 | |
| 61 | impl 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 | } |