use std::{
borrow::Borrow,
fmt::{Debug, Formatter},
iter::Sum,
ops::{Add, Deref, Index, IndexMut},
};
pub mod my_visitor;
use imbl::{shared_ptr::DefaultSharedPtr, Vector};
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
#[macro_export]
macro_rules! inOMap {
() => { $crate::in_order_map::InOMap::new() };
( $( $key:expr => $value:expr ),* ) => {{
let mut map = $crate::in_order_map::InOMap::new();
$({
map.insert($key, $value);
})*;
map
}};
( $( $key:expr => $value:expr ,)* ) => {{
let mut map = $crate::in_order_map::InOMap::new();
$({
map.insert($key, $value);
})*;
map
}};
}
#[derive(Clone)]
pub struct InOMap<K, V>
where
K: Eq + Clone,
V: Clone,
{
value: Vector<(K, V)>,
}
impl<K, V> From<Vector<(K, V)>> for InOMap<K, V>
where
K: Eq + Clone,
V: Clone,
{
fn from(value: Vector<(K, V)>) -> Self {
Self { value }
}
}
impl<K, V> From<InOMap<K, V>> for Vector<(K, V)>
where
K: Eq + Clone,
V: Clone,
{
fn from(value: InOMap<K, V>) -> Self {
value.value
}
}
impl<K, V> PartialEq for InOMap<K, V>
where
K: Eq + Clone,
V: Eq + Clone,
{
fn eq(&self, other: &Self) -> bool {
self.value.ptr_eq(&other.value) || self.value == other.value || {
self.value.len() == other.value.len() && {
self.value.iter().all(|(k, v)| other.get(k) == Some(v))
}
}
}
}
impl<K, V> Serialize for InOMap<K, V>
where
K: Serialize + Eq + Clone,
V: Serialize + Clone,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(self.len()))?;
for (k, v) in self {
map.serialize_entry(k, v)?;
}
map.end()
}
}
impl<'de, K, V> Deserialize<'de> for InOMap<K, V>
where
K: Deserialize<'de> + Clone + Eq + Deref,
V: Deserialize<'de> + Clone,
<K as Deref>::Target: Eq,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(my_visitor::MyVisitor::new())
}
}
impl<K, V> InOMap<K, V>
where
K: Eq + Clone,
V: Clone,
{
#[inline]
#[must_use]
pub fn new() -> Self {
Self {
value: Default::default(),
}
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.value.is_empty()
}
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.value.len()
}
}
impl<K, V> InOMap<K, V>
where
K: Eq + Clone,
V: Clone,
{
pub fn ptr_eq(&self, other: &Self) -> bool {
self.value.ptr_eq(&other.value)
}
}
impl<K, V> InOMap<K, V>
where
K: Eq + Clone,
V: Clone,
{
#[inline]
#[must_use]
pub fn iter(&self) -> imbl::vector::Iter<'_, (K, V), DefaultSharedPtr> {
self.value.iter()
}
#[inline]
#[must_use]
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.iter().map(|(key, _value)| key)
}
#[inline]
#[must_use]
pub fn values(&self) -> impl Iterator<Item = &V> {
self.iter().map(|(_key, value)| value)
}
pub fn clear(&mut self) {
self.value.clear();
}
}
impl<K, V> InOMap<K, V>
where
V: Clone,
K: Eq + Clone,
{
#[must_use]
pub fn get<BK>(&self, key: &BK) -> Option<&V>
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
let key = key.borrow();
self.iter().find(|(k, _)| k == key).map(|x| &x.1)
}
#[must_use]
pub fn get_key_value<BK>(&self, key: &BK) -> Option<(&K, &V)>
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
self.iter().find(|(k, _)| k == key).map(|(k, v)| (k, v))
}
#[inline]
#[must_use]
pub fn contains_key<BK>(&self, k: &BK) -> bool
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
self.get(&k).is_some()
}
#[must_use]
pub fn is_submap_by<B, RM, F>(&self, other: RM, mut cmp: F) -> bool
where
B: Clone,
F: FnMut(&V, &B) -> bool,
RM: Borrow<InOMap<K, B>>,
{
self.value
.iter()
.all(|(k, v)| other.borrow().get(k).map(|ov| cmp(v, ov)).unwrap_or(false))
}
#[must_use]
pub fn is_proper_submap_by<B, RM, F>(&self, other: RM, cmp: F) -> bool
where
B: Clone,
F: FnMut(&V, &B) -> bool,
RM: Borrow<InOMap<K, B>>,
{
self.value.len() != other.borrow().value.len() && self.is_submap_by(other, cmp)
}
#[inline]
#[must_use]
pub fn is_submap<RM>(&self, other: RM) -> bool
where
V: PartialEq,
RM: Borrow<Self>,
{
self.is_submap_by(other.borrow(), PartialEq::eq)
}
#[inline]
#[must_use]
pub fn is_proper_submap<RM>(&self, other: RM) -> bool
where
V: PartialEq,
RM: Borrow<Self>,
{
self.is_proper_submap_by(other.borrow(), PartialEq::eq)
}
}
impl<K, V> InOMap<K, V>
where
V: Clone,
K: Eq + Clone,
{
#[inline]
#[must_use]
pub fn iter_mut(&mut self) -> imbl::vector::IterMut<'_, (K, V), DefaultSharedPtr> {
self.value.iter_mut()
}
#[must_use]
pub fn get_mut<BK>(&mut self, key: &BK) -> Option<&mut V>
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
self.value
.iter_mut()
.find(|(k, _)| k == key.borrow())
.map(|(_, v)| v)
}
#[inline]
pub fn insert(&mut self, key: K, v: V) -> Option<V> {
let previous = self
.value
.iter()
.enumerate()
.find(|(_, (k, _))| k == &key)
.map(|(index, _)| index)
.map(|x| self.value.remove(x));
self.value.push_back((key, v));
previous.map(|(_, v)| v)
}
pub fn remove<BK>(&mut self, k: &BK) -> Option<V>
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
self.value
.iter()
.enumerate()
.find(|x| &x.1 .0 == &*k)
.map(|x| x.0)
.map(|x| self.value.remove(x))
.map(|x| x.1)
}
pub fn remove_with_key<BK>(&mut self, k: &BK) -> Option<(K, V)>
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
self.value
.iter()
.enumerate()
.find(|x| &x.1 .0 == &*k)
.map(|x| x.0)
.map(|x| self.value.remove(x))
}
#[must_use]
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
let found_index = self
.value
.iter()
.enumerate()
.find(|x| &x.1 .0 == &key)
.map(|x| x.0);
if let Some(index) = found_index {
Entry::Occupied(OccupiedEntry {
map: self,
key,
index,
})
} else {
Entry::Vacant(VacantEntry { map: self, key })
}
}
#[inline]
#[must_use]
pub fn update(&self, k: K, v: V) -> Self {
let mut out = self.clone();
out.insert(k, v);
out
}
#[must_use]
pub fn update_with<F>(&self, k: K, v: V, f: F) -> Self
where
F: FnOnce(V, V) -> V,
{
match self.extract_with_key(&k) {
None => self.update(k, v),
Some((_, v2, m)) => m.update(k, f(v2, v)),
}
}
#[must_use]
pub fn update_with_key<F>(&self, k: K, v: V, f: F) -> Self
where
F: FnOnce(&K, V, V) -> V,
{
match self.extract_with_key(&k) {
None => self.update(k, v),
Some((_, v2, m)) => {
let out_v = f(&k, v2, v);
m.update(k, out_v)
}
}
}
#[must_use]
pub fn update_lookup_with_key<F>(&self, k: K, v: V, f: F) -> (Option<V>, Self)
where
F: FnOnce(&K, &V, V) -> V,
{
match self.extract_with_key(&k) {
None => (None, self.update(k, v)),
Some((_, v2, m)) => {
let out_v = f(&k, &v2, v);
(Some(v2), m.update(k, out_v))
}
}
}
#[must_use]
pub fn alter<F>(&self, f: F, k: K) -> Self
where
F: FnOnce(Option<V>) -> Option<V>,
{
let pop = self.extract_with_key(&k);
match (f(pop.as_ref().map(|&(_, ref v, _)| v.clone())), pop) {
(None, None) => self.clone(),
(Some(v), None) => self.update(k, v),
(None, Some((_, _, m))) => m,
(Some(v), Some((_, _, m))) => m.update(k, v),
}
}
#[must_use]
pub fn without<BK>(&self, k: &BK) -> Self
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
match self.extract_with_key(k) {
None => self.clone(),
Some((_, _, map)) => map,
}
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&K, &V) -> bool,
{
self.value.retain(|(k, v)| f(k, v));
}
#[must_use]
pub fn extract<BK>(&self, k: &BK) -> Option<(V, Self)>
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
self.extract_with_key(k).map(|(_, v, m)| (v, m))
}
#[must_use]
pub fn extract_with_key<BK>(&self, k: &BK) -> Option<(K, V, Self)>
where
BK: Eq + ?Sized,
K: Borrow<BK> + PartialEq<BK>,
{
let mut out = self.clone();
out.remove_with_key(k).map(|(k, v)| (k, v, out))
}
#[must_use]
pub fn union(self, other: Self) -> Self {
let (mut to_mutate, to_consume, use_to_consume) = if self.len() >= other.len() {
(self, other, false)
} else {
(other, self, true)
};
for (k, v) in to_consume.value.into_iter().rev() {
match to_mutate.entry(k) {
Entry::Occupied(mut e) if use_to_consume => {
e.insert(v);
}
Entry::Vacant(e) => {
e.insert(v);
}
_ => {}
}
}
to_mutate.value = to_mutate.value.clone().into_iter().rev().collect();
to_mutate
}
#[inline]
#[must_use]
pub fn union_with<F>(self, other: Self, mut f: F) -> Self
where
F: FnMut(V, V) -> V,
{
self.union_with_key(other, |_, v1, v2| f(v1, v2))
}
#[must_use]
pub fn union_with_key<F>(self, other: Self, mut f: F) -> Self
where
F: FnMut(&K, V, V) -> V,
{
if self.len() >= other.len() {
self.union_with_key_inner(other, f)
} else {
other.union_with_key_inner(self, |key, other_value, self_value| {
f(key, self_value, other_value)
})
}
}
fn union_with_key_inner<F>(mut self, other: Self, mut f: F) -> Self
where
F: FnMut(&K, V, V) -> V,
{
for (key, right_value) in other {
match self.remove(&key) {
None => {
self.insert(key, right_value);
}
Some(left_value) => {
let final_value = f(&key, left_value, right_value);
self.insert(key, final_value);
}
}
}
self
}
#[must_use]
pub fn unions<I>(i: I) -> Self
where
I: IntoIterator<Item = Self>,
{
i.into_iter().fold(Self::default(), Self::union)
}
#[must_use]
pub fn unions_with<I, F>(i: I, f: F) -> Self
where
I: IntoIterator<Item = Self>,
F: Fn(V, V) -> V,
{
i.into_iter()
.fold(Self::default(), |a, b| a.union_with(b, &f))
}
#[must_use]
pub fn unions_with_key<I, F>(i: I, f: F) -> Self
where
I: IntoIterator<Item = Self>,
F: Fn(&K, V, V) -> V,
{
i.into_iter()
.fold(Self::default(), |a, b| a.union_with_key(b, &f))
}
#[deprecated(
since = "2.0.1",
note = "to avoid conflicting behaviors between std and imbl, the `difference` alias for `symmetric_difference` will be removed."
)]
#[inline]
#[must_use]
pub fn difference(self, other: Self) -> Self {
self.symmetric_difference(other)
}
#[inline]
#[must_use]
pub fn symmetric_difference(self, other: Self) -> Self {
self.symmetric_difference_with_key(other, |_, _, _| None)
}
#[deprecated(
since = "2.0.1",
note = "to avoid conflicting behaviors between std and imbl, the `difference_with` alias for `symmetric_difference_with` will be removed."
)]
#[inline]
#[must_use]
pub fn difference_with<F>(self, other: Self, f: F) -> Self
where
F: FnMut(V, V) -> Option<V>,
{
self.symmetric_difference_with(other, f)
}
#[inline]
#[must_use]
pub fn symmetric_difference_with<F>(self, other: Self, mut f: F) -> Self
where
F: FnMut(V, V) -> Option<V>,
{
self.symmetric_difference_with_key(other, |_, a, b| f(a, b))
}
#[deprecated(
since = "2.0.1",
note = "to avoid conflicting behaviors between std and imbl, the `difference_with_key` alias for `symmetric_difference_with_key` will be removed."
)]
#[must_use]
pub fn difference_with_key<F>(self, other: Self, f: F) -> Self
where
F: FnMut(&K, V, V) -> Option<V>,
{
self.symmetric_difference_with_key(other, f)
}
#[must_use]
pub fn symmetric_difference_with_key<F>(mut self, other: Self, mut f: F) -> Self
where
F: FnMut(&K, V, V) -> Option<V>,
{
let mut out = InOMap::default();
for (key, right_value) in other {
match self.remove(&key) {
None => {
out.insert(key, right_value);
}
Some(left_value) => {
if let Some(final_value) = f(&key, left_value, right_value) {
out.insert(key, final_value);
}
}
}
}
out.union(self)
}
#[inline]
#[must_use]
pub fn relative_complement(mut self, other: Self) -> Self {
for (key, _) in other {
let _ = self.remove(&key);
}
self
}
#[inline]
#[must_use]
pub fn intersection(self, other: Self) -> Self {
self.intersection_with_key(other, |_, v, _| v)
}
#[inline]
#[must_use]
pub fn intersection_with<B, C, F>(self, other: InOMap<K, B>, mut f: F) -> InOMap<K, C>
where
B: Clone,
C: Clone,
F: FnMut(V, B) -> C,
{
self.intersection_with_key(other, |_, v1, v2| f(v1, v2))
}
#[must_use]
pub fn intersection_with_key<B, C, F>(mut self, other: InOMap<K, B>, mut f: F) -> InOMap<K, C>
where
B: Clone,
C: Clone,
F: FnMut(&K, V, B) -> C,
{
let mut out = InOMap::default();
for (key, right_value) in other {
match self.remove(&key) {
None => (),
Some(left_value) => {
let result = f(&key, left_value, right_value);
out.insert(key, result);
}
}
}
out
}
}
pub enum Entry<'a, K, V>
where
V: Clone,
K: Eq + Clone,
{
Occupied(OccupiedEntry<'a, K, V>),
Vacant(VacantEntry<'a, K, V>),
}
impl<'a, K, V> Entry<'a, K, V>
where
V: 'a + Clone,
K: 'a + Eq + Clone,
{
pub fn or_insert(self, default: V) -> &'a mut V {
self.or_insert_with(|| default)
}
pub fn or_insert_with<F>(self, default: F) -> &'a mut V
where
F: FnOnce() -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default()),
}
}
pub fn or_default(self) -> &'a mut V
where
V: Default,
{
self.or_insert_with(Default::default)
}
#[must_use]
pub fn key(&self) -> &K {
match self {
Entry::Occupied(entry) => entry.key(),
Entry::Vacant(entry) => entry.key(),
}
}
#[must_use]
pub fn and_modify<F>(mut self, f: F) -> Self
where
F: FnOnce(&mut V),
{
match &mut self {
Entry::Occupied(ref mut entry) => f(entry.get_mut()),
Entry::Vacant(_) => (),
}
self
}
}
pub struct OccupiedEntry<'a, K, V>
where
V: Clone,
K: Eq + Clone,
{
map: &'a mut InOMap<K, V>,
index: usize,
key: K,
}
impl<'a, K, V> OccupiedEntry<'a, K, V>
where
K: 'a + Eq + Clone,
V: 'a + Clone,
{
#[must_use]
pub fn key(&self) -> &K {
&self.key
}
pub fn remove_entry(self) -> (K, V) {
self.map.remove_with_key(&self.key).unwrap()
}
#[must_use]
pub fn get(&self) -> &V {
&self.map.value.get(self.index).unwrap().1
}
#[must_use]
pub fn get_mut(&mut self) -> &mut V {
&mut self.map.value.get_mut(self.index).unwrap().1
}
#[must_use]
pub fn into_mut(self) -> &'a mut V {
&mut self.map.value.get_mut(self.index).unwrap().1
}
pub fn insert(&mut self, mut value: V) -> V {
::std::mem::swap(
&mut self.map.value.get_mut(self.index).unwrap().1,
&mut value,
);
value
}
pub fn remove(self) -> V {
self.remove_entry().1
}
}
pub struct VacantEntry<'a, K, V>
where
V: Clone,
K: Eq + Clone,
{
map: &'a mut InOMap<K, V>,
key: K,
}
impl<'a, K, V> VacantEntry<'a, K, V>
where
K: 'a + Eq + Clone,
V: 'a + Clone,
{
#[must_use]
pub fn key(&self) -> &K {
&self.key
}
#[must_use]
pub fn into_key(self) -> K {
self.key
}
pub fn insert(self, value: V) -> &'a mut V {
self.map.insert(self.key.clone(), value);
self.map.get_mut(&self.key).unwrap()
}
}
impl<K, V> Add for InOMap<K, V>
where
V: Clone,
K: Eq + Clone,
{
type Output = InOMap<K, V>;
fn add(self, other: Self) -> Self::Output {
self.union(other)
}
}
impl<'a, K, V> Add for &'a InOMap<K, V>
where
V: Clone,
K: Eq + Clone,
{
type Output = InOMap<K, V>;
fn add(self, other: Self) -> Self::Output {
self.clone().union(other.clone())
}
}
impl<K, V> Sum for InOMap<K, V>
where
V: Clone,
K: Eq + Clone,
{
fn sum<I>(it: I) -> Self
where
I: Iterator<Item = Self>,
{
it.fold(Self::default(), |a, b| a + b)
}
}
impl<K, V, RK, RV> Extend<(RK, RV)> for InOMap<K, V>
where
V: Clone + From<RV>,
K: Eq + Clone + From<RK>,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = (RK, RV)>,
{
for (key, value) in iter {
self.insert(From::from(key), From::from(value));
}
}
}
impl<'a, BK, K, V> Index<&'a BK> for InOMap<K, V>
where
V: Clone,
BK: Eq + ?Sized,
K: Eq + Clone + Borrow<BK> + PartialEq<BK>,
{
type Output = V;
fn index(&self, key: &BK) -> &Self::Output {
match self.get::<BK>(key) {
None => panic!("InOMap::index: invalid key"),
Some(v) => v,
}
}
}
impl<'a, BK, K, V> IndexMut<&'a BK> for InOMap<K, V>
where
BK: Eq + ?Sized,
K: Eq + Clone + Borrow<BK> + PartialEq<BK>,
V: Clone,
{
fn index_mut(&mut self, key: &BK) -> &mut Self::Output {
match self.get_mut::<BK>(key) {
None => panic!("InOMap::index_mut: invalid key"),
Some(&mut ref mut value) => value,
}
}
}
impl<K, V> Debug for InOMap<K, V>
where
V: Clone,
K: Eq + Debug + Clone,
V: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), ::std::fmt::Error> {
let mut d = f.debug_map();
for (k, v) in self {
d.entry(k, v);
}
d.finish()
}
}
pub struct Iter<'a, K, V>
where
K: Clone,
V: Clone,
{
it: imbl::vector::Iter<'a, (K, V), DefaultSharedPtr>,
}
impl<'a, K, V> Clone for Iter<'a, K, V>
where
K: Clone,
V: Clone,
{
fn clone(&self) -> Self {
Iter {
it: self.it.clone(),
}
}
}
impl<'a, K, V> Iterator for Iter<'a, K, V>
where
K: Clone,
V: Clone,
{
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.it.next().map(|(k, v)| (k, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.it.size_hint()
}
}
impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V>
where
K: Clone,
V: Clone,
{
}
impl<'a, K, V> IntoIterator for &'a InOMap<K, V>
where
K: Eq + Clone,
V: Clone,
{
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Iter {
it: self.value.iter(),
}
}
}
impl<K, V> IntoIterator for InOMap<K, V>
where
K: Eq + Clone,
V: Clone,
{
type Item = (K, V);
type IntoIter = imbl::vector::ConsumingIter<(K, V), DefaultSharedPtr>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.value.into_iter()
}
}
impl<K, V> FromIterator<(K, V)> for InOMap<K, V>
where
V: Clone,
K: Eq + Clone,
{
fn from_iter<T>(i: T) -> Self
where
T: IntoIterator<Item = (K, V)>,
{
let mut map = Self::default();
for (k, v) in i {
map.insert(k, v);
}
map
}
}
impl<K, V> Default for InOMap<K, V>
where
K: Clone + Eq,
V: Clone,
{
fn default() -> Self {
Self {
value: Default::default(),
}
}
}
impl<K, V> AsRef<InOMap<K, V>> for InOMap<K, V>
where
K: Eq + Clone,
V: Clone,
{
#[inline]
fn as_ref(&self) -> &Self {
self
}
}