use indexmap::IndexMap;
use std::collections::HashMap;
use std::collections::VecDeque;
#[derive(Debug, Clone)]
pub struct Mict<K, V>
where
K: std::hash::Hash + Eq + Clone,
V: Clone,
{
data: IndexMap<K, VecDeque<V>>,
}
impl<K, V> Mict<K, V>
where
K: std::hash::Hash + Eq + Clone,
V: Clone,
{
pub fn new() -> Self {
Self {
data: IndexMap::new(),
}
}
pub fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
{
let mut mict = Self::new();
for (key, value) in iter {
mict.add(key, value);
}
mict
}
pub fn add(&mut self, key: K, value: V) {
self.data
.entry(key)
.or_insert_with(VecDeque::new)
.push_back(value);
}
pub fn set(&mut self, key: K, value: V) {
let mut deque = VecDeque::new();
deque.push_back(value);
self.data.insert(key, deque);
}
pub fn get(&self, key: &K) -> Option<&V> {
self.data.get(key).and_then(|deque| deque.front())
}
pub fn get_last(&self, key: &K) -> Option<&V> {
self.data.get(key).and_then(|deque| deque.back())
}
pub fn nab(&self, key: &K, default: Option<V>) -> Option<V> {
match self.data.get(key).and_then(|deque| deque.back()) {
Some(value) => Some(value.clone()),
None => default,
}
}
pub fn nabone(&self, key: &K) -> Result<V, String> {
match self.data.get(key).and_then(|deque| deque.back()) {
Some(value) => Ok(value.clone()),
None => Err(format!("Key not found: {:?}", std::any::type_name::<K>())),
}
}
pub fn get_all(&self, key: &K) -> Vec<V> {
match self.data.get(key) {
Some(deque) => deque.iter().cloned().collect(),
None => Vec::new(),
}
}
pub fn naball(&self, key: &K, default: Option<Vec<V>>) -> Option<Vec<V>> {
match self.data.get(key) {
Some(deque) => {
let mut values: Vec<V> = deque.iter().cloned().collect();
values.reverse();
Some(values)
}
None => default,
}
}
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.data.keys()
}
pub fn values(&self) -> impl Iterator<Item = &V> {
self.data.values().flat_map(|deque| deque.iter())
}
pub fn firsts(&self) -> Vec<(K, V)> {
self.data
.iter()
.filter_map(|(k, deque)| deque.front().map(|v| (k.clone(), v.clone())))
.collect()
}
pub fn lasts(&self) -> Vec<(K, V)> {
self.data
.iter()
.filter_map(|(k, deque)| deque.back().map(|v| (k.clone(), v.clone())))
.collect()
}
pub fn contains_key(&self, key: &K) -> bool {
self.data.contains_key(key)
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn items(&self) -> impl Iterator<Item = (K, V)> + '_ {
self.data
.iter()
.flat_map(|(k, deque)| deque.iter().map(move |v| (k.clone(), v.clone())))
}
}
impl<K, V> Default for Mict<K, V>
where
K: std::hash::Hash + Eq + Clone,
V: Clone,
{
fn default() -> Self {
Self::new()
}
}
impl<K, V> std::fmt::Display for Mict<K, V>
where
K: std::hash::Hash + Eq + Clone + std::fmt::Debug,
V: Clone + std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Mict({:?})", self.items().collect::<Vec<_>>())
}
}