use std::collections::{BTreeMap, HashMap};
use std::error::Error;
use std::fmt::Debug;
use std::hash::Hash;
use std::ops::{Deref, DerefMut};
use thiserror::Error;
#[derive(Error, Debug, PartialEq)]
#[error("vec requires keys to be consecutive. You tried to add a key that did not directly follow the previous key.")]
pub struct NotInOrder;
#[derive(Error, Debug, PartialEq)]
#[error("this key was already in the mapping, and thus cannot be added. consider using `set` or `set_or_add`")]
pub struct AlreadyIn;
#[derive(Error, Debug, PartialEq)]
#[error("union find doesn't support adding more keys")]
pub struct Full;
pub trait ParentMapping<T>: Mapping<T, T> + Sized {
type Err: Error;
fn identity_map<I: IntoIterator<Item = T>>(items: I) -> Result<Self, Self::Err>;
}
pub trait RankMapping<T>: GrowableMapping<T, usize> {
type Err: Error;
fn zero_map<I: IntoIterator<Item = T>>(items: I) -> Result<Self, Self::Err>
where
Self: Sized;
}
impl<T, K: Clone> ParentMapping<K> for T
where
T: GrowableIdentityMapping<K>,
K: Clone,
{
type Err = <T as GrowableMapping<K, K>>::AddError;
fn identity_map<I: IntoIterator<Item = K>>(items: I) -> Result<Self, Self::Err> {
let mut map = Self::empty();
for i in items {
map.add_identity(i)?
}
Ok(map)
}
}
impl<M, T> RankMapping<T> for M
where
M: GrowableMapping<T, usize>,
{
type Err = <M as GrowableMapping<T, usize>>::AddError;
fn zero_map<I: IntoIterator<Item = T>>(items: I) -> Result<Self, Self::Err> {
let mut map = Self::empty();
for i in items {
map.add(i, 0)?
}
Ok(map)
}
}
pub trait Mapping<K, V> {
fn get(&self, key: &K) -> Option<&V>;
fn contains_key(&self, key: &K) -> bool {
self.get(key).is_some()
}
fn set(&mut self, key: K, value: V);
}
pub trait GrowableIdentityMapping<T>: GrowableMapping<T, T>
where
T: Clone,
{
fn add_identity(&mut self, key: T) -> Result<(), Self::AddError> {
self.add(key.clone(), key)
}
}
impl<T: Clone, M> GrowableIdentityMapping<T> for M where M: GrowableMapping<T, T> {}
pub trait GrowableMapping<K, V>: Mapping<K, V> {
type AddError: Error + Debug;
fn empty() -> Self;
fn set_or_add(&mut self, key: K, value: V) -> Result<bool, Self::AddError> {
if self.contains_key(&key) {
self.set(key, value);
Ok(false)
} else {
self.add(key, value)?;
Ok(true)
}
}
fn add(&mut self, key: K, value: V) -> Result<(), Self::AddError>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<K: Hash + Eq, V> Mapping<K, V> for HashMap<K, V> {
fn get(&self, key: &K) -> Option<&V> {
HashMap::get(self, key)
}
fn set(&mut self, key: K, value: V) {
if self.insert(key, value).is_none() {
panic!("can't set value of element which is not yet in mapping")
}
}
}
impl<K: Hash + Eq, V> GrowableMapping<K, V> for HashMap<K, V> {
type AddError = AlreadyIn;
fn empty() -> Self {
HashMap::new()
}
fn add(&mut self, key: K, value: V) -> Result<(), Self::AddError> {
if self.insert(key, value).is_some() {
return Err(AlreadyIn);
}
Ok(())
}
fn len(&self) -> usize {
HashMap::len(self)
}
}
impl<K: Ord, V> Mapping<K, V> for BTreeMap<K, V> {
fn get(&self, key: &K) -> Option<&V> {
BTreeMap::get(self, key)
}
fn set(&mut self, key: K, value: V) {
if self.insert(key, value).is_none() {
panic!("can't set value of element which is not yet in mapping")
}
}
}
impl<K: Ord, V> GrowableMapping<K, V> for BTreeMap<K, V> {
type AddError = AlreadyIn;
fn empty() -> Self {
BTreeMap::new()
}
fn add(&mut self, key: K, value: V) -> Result<(), Self::AddError> {
if self.insert(key, value).is_some() {
return Err(AlreadyIn);
}
Ok(())
}
fn len(&self) -> usize {
BTreeMap::len(self)
}
}
impl<V, const N: usize> Mapping<usize, V> for [V; N] {
fn get(&self, key: &usize) -> Option<&V> {
if *key < self.len() {
Some(&self[*key])
} else {
None
}
}
fn set(&mut self, key: usize, value: V) {
if key < self.len() {
self[key] = value;
} else {
panic!("can't set value of element which is not yet in mapping");
}
}
}
impl<V> Mapping<usize, V> for [V] {
fn get(&self, key: &usize) -> Option<&V> {
if *key < self.len() {
Some(&self[*key])
} else {
None
}
}
fn set(&mut self, key: usize, value: V) {
if key < self.len() {
self[key] = value;
} else {
panic!("can't set value of element which is not yet in mapping");
}
}
}
impl<V> Mapping<usize, V> for Vec<V> {
fn get(&self, key: &usize) -> Option<&V> {
if *key < self.len() {
Some(&self[*key])
} else {
None
}
}
fn set(&mut self, key: usize, value: V) {
if key < self.len() {
self[key] = value;
} else {
panic!("can't set value of element which is not yet in mapping");
}
}
}
impl<V> GrowableMapping<usize, V> for Vec<V> {
type AddError = NotInOrder;
fn empty() -> Self {
Vec::new()
}
fn add(&mut self, key: usize, value: V) -> Result<(), Self::AddError> {
if key == self.len() {
self.push(value);
Ok(())
} else {
Err(NotInOrder)
}
}
fn len(&self) -> usize {
Vec::len(self)
}
}
struct FixedSize<M>(M);
impl<M> Deref for FixedSize<M> {
type Target = M;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<M> DerefMut for FixedSize<M> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<K, V, M> Mapping<K, V> for FixedSize<M>
where
M: Mapping<K, V>,
{
fn get(&self, key: &K) -> Option<&V> {
self.0.get(key)
}
fn set(&mut self, key: K, value: V) {
self.0.set(key, value);
}
}