diff options
Diffstat (limited to 'vendor/clap_builder/src/util/flat_map.rs')
-rw-r--r-- | vendor/clap_builder/src/util/flat_map.rs | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/vendor/clap_builder/src/util/flat_map.rs b/vendor/clap_builder/src/util/flat_map.rs new file mode 100644 index 0000000..468f0a9 --- /dev/null +++ b/vendor/clap_builder/src/util/flat_map.rs @@ -0,0 +1,254 @@ +#![allow(dead_code)] + +use std::borrow::Borrow; + +/// Flat (Vec) backed map +/// +/// This preserves insertion order +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct FlatMap<K, V> { + keys: Vec<K>, + values: Vec<V>, +} + +impl<K: PartialEq + Eq, V> FlatMap<K, V> { + pub(crate) fn new() -> Self { + Default::default() + } + + pub(crate) fn insert(&mut self, key: K, mut value: V) -> Option<V> { + for (index, existing) in self.keys.iter().enumerate() { + if *existing == key { + std::mem::swap(&mut self.values[index], &mut value); + return Some(value); + } + } + + self.insert_unchecked(key, value); + None + } + + pub(crate) fn insert_unchecked(&mut self, key: K, value: V) { + self.keys.push(key); + self.values.push(value); + } + + pub(crate) fn extend_unchecked(&mut self, iter: impl IntoIterator<Item = (K, V)>) { + for (key, value) in iter { + self.insert_unchecked(key, value); + } + } + + pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool + where + K: Borrow<Q>, + Q: Eq, + { + for existing in &self.keys { + if existing.borrow() == key { + return true; + } + } + false + } + + pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> + where + K: Borrow<Q>, + Q: std::hash::Hash + Eq, + { + self.remove_entry(key).map(|(_, v)| v) + } + + pub fn remove_entry<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, V)> + where + K: Borrow<Q>, + Q: std::hash::Hash + Eq, + { + let index = some!(self + .keys + .iter() + .enumerate() + .find_map(|(i, k)| (k.borrow() == key).then_some(i))); + let key = self.keys.remove(index); + let value = self.values.remove(index); + Some((key, value)) + } + + pub(crate) fn is_empty(&self) -> bool { + self.keys.is_empty() + } + + pub fn entry(&mut self, key: K) -> Entry<K, V> { + for (index, existing) in self.keys.iter().enumerate() { + if *existing == key { + return Entry::Occupied(OccupiedEntry { v: self, index }); + } + } + Entry::Vacant(VacantEntry { v: self, key }) + } + + pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> + where + K: Borrow<Q>, + Q: Eq, + { + for (index, existing) in self.keys.iter().enumerate() { + if existing.borrow() == k { + return Some(&self.values[index]); + } + } + None + } + + pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> + where + K: Borrow<Q>, + Q: Eq, + { + for (index, existing) in self.keys.iter().enumerate() { + if existing.borrow() == k { + return Some(&mut self.values[index]); + } + } + None + } + + pub fn keys(&self) -> std::slice::Iter<'_, K> { + self.keys.iter() + } + + pub fn iter(&self) -> Iter<K, V> { + Iter { + keys: self.keys.iter(), + values: self.values.iter(), + } + } + + pub fn iter_mut(&mut self) -> IterMut<K, V> { + IterMut { + keys: self.keys.iter_mut(), + values: self.values.iter_mut(), + } + } +} + +impl<K: PartialEq + Eq, V> Default for FlatMap<K, V> { + fn default() -> Self { + Self { + keys: Default::default(), + values: Default::default(), + } + } +} + +pub enum Entry<'a, K: 'a, V: 'a> { + Vacant(VacantEntry<'a, K, V>), + Occupied(OccupiedEntry<'a, K, V>), +} + +impl<'a, K: 'a, V: 'a> Entry<'a, K, V> { + pub fn or_insert(self, default: V) -> &'a mut V { + match self { + Entry::Occupied(entry) => &mut entry.v.values[entry.index], + Entry::Vacant(entry) => { + entry.v.keys.push(entry.key); + entry.v.values.push(default); + entry.v.values.last_mut().unwrap() + } + } + } + + pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V { + match self { + Entry::Occupied(entry) => &mut entry.v.values[entry.index], + Entry::Vacant(entry) => { + entry.v.keys.push(entry.key); + entry.v.values.push(default()); + entry.v.values.last_mut().unwrap() + } + } + } +} + +pub struct VacantEntry<'a, K: 'a, V: 'a> { + v: &'a mut FlatMap<K, V>, + key: K, +} + +pub struct OccupiedEntry<'a, K: 'a, V: 'a> { + v: &'a mut FlatMap<K, V>, + index: usize, +} + +pub struct Iter<'a, K: 'a, V: 'a> { + keys: std::slice::Iter<'a, K>, + values: std::slice::Iter<'a, V>, +} + +impl<'a, K, V> Iterator for Iter<'a, K, V> { + type Item = (&'a K, &'a V); + + fn next(&mut self) -> Option<(&'a K, &'a V)> { + match self.keys.next() { + Some(k) => { + let v = self.values.next().unwrap(); + Some((k, v)) + } + None => None, + } + } + fn size_hint(&self) -> (usize, Option<usize>) { + self.keys.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> { + fn next_back(&mut self) -> Option<(&'a K, &'a V)> { + match self.keys.next_back() { + Some(k) => { + let v = self.values.next_back().unwrap(); + Some((k, v)) + } + None => None, + } + } +} + +impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {} + +pub struct IterMut<'a, K: 'a, V: 'a> { + keys: std::slice::IterMut<'a, K>, + values: std::slice::IterMut<'a, V>, +} + +impl<'a, K, V> Iterator for IterMut<'a, K, V> { + type Item = (&'a K, &'a mut V); + + fn next(&mut self) -> Option<(&'a K, &'a mut V)> { + match self.keys.next() { + Some(k) => { + let v = self.values.next().unwrap(); + Some((k, v)) + } + None => None, + } + } + fn size_hint(&self) -> (usize, Option<usize>) { + self.keys.size_hint() + } +} + +impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> { + fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> { + match self.keys.next_back() { + Some(k) => { + let v = self.values.next_back().unwrap(); + Some((k, v)) + } + None => None, + } + } +} + +impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {} |