use std::borrow::Borrow;
use std::fmt;
use std::slice::{Iter, IterMut};
use std::vec::IntoIter;
use crate::vec::{Entry, OccupiedEntry, VacantEntry};
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Keys<'a, K: 'a, V: 'a> {
inner: Iter<'a, (K, V)>,
}
impl<'a, K, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;
fn next(&mut self) -> Option<&'a K> {
self.inner.next().map(|(k, _)| k)
}
}
impl<K: fmt::Debug, V> fmt::Debug for Keys<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<K, V> Clone for Keys<'_, K, V> {
fn clone(&self) -> Self {
Keys {
inner: self.inner.clone(),
}
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct IntoKeys<K, V> {
inner: IntoIter<(K, V)>,
}
impl<K, V> Iterator for IntoKeys<K, V> {
type Item = K;
fn next(&mut self) -> Option<K> {
self.inner.next().map(|(k, _)| k)
}
}
impl<K: fmt::Debug, V> fmt::Debug for IntoKeys<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list()
.entries(self.inner.as_slice().iter().map(|(k, _)| k))
.finish()
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Values<'a, K: 'a, V: 'a> {
inner: Iter<'a, (K, V)>,
}
impl<'a, K, V> Iterator for Values<'a, K, V> {
type Item = &'a V;
fn next(&mut self) -> Option<&'a V> {
self.inner.next().map(|(_, v)| v)
}
}
impl<K, V: fmt::Debug> fmt::Debug for Values<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<K, V> Clone for Values<'_, K, V> {
fn clone(&self) -> Self {
Values {
inner: self.inner.clone(),
}
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ValuesMut<'a, K: 'a, V: 'a> {
inner: IterMut<'a, (K, V)>,
}
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
type Item = &'a mut V;
fn next(&mut self) -> Option<&'a mut V> {
self.inner.next().map(|(_, v)| v)
}
}
impl<K, V: fmt::Debug> fmt::Debug for ValuesMut<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list()
.entries(self.inner.as_slice().iter().map(|(_, v)| v))
.finish()
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct IntoValues<K, V> {
inner: IntoIter<(K, V)>,
}
impl<K, V> Iterator for IntoValues<K, V> {
type Item = V;
fn next(&mut self) -> Option<V> {
self.inner.next().map(|(_, v)| v)
}
}
impl<K, V: fmt::Debug> fmt::Debug for IntoValues<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list()
.entries(self.inner.as_slice().iter().map(|(_, v)| v))
.finish()
}
}
pub trait AssocExt<K, V> {
fn entry(&mut self, key: K) -> Entry<K, V>;
fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized;
fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized;
fn insert(&mut self, key: K, value: V) -> Option<V>;
fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized;
fn keys(&self) -> Keys<'_, K, V>;
fn into_keys(self) -> IntoKeys<K, V>;
fn values(&self) -> Values<'_, K, V>;
fn values_mut(&mut self) -> ValuesMut<'_, K, V>;
fn into_values(self) -> IntoValues<K, V>;
}
impl<K, V> AssocExt<K, V> for Vec<(K, V)>
where
K: PartialEq,
{
fn entry(&mut self, key: K) -> Entry<K, V> {
let found = self.iter_mut().enumerate().find(|(_, (k, _))| k == &key);
match found {
None => Entry::Vacant(VacantEntry::new(self, key)),
Some((index, _)) => Entry::Occupied(OccupiedEntry::new(self, key, index)),
}
}
fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized,
{
self.iter().find(|(k, _)| k.borrow() == key).map(|(_, v)| v)
}
fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized,
{
self.iter_mut()
.find(|(k, _)| k.borrow() == key)
.map(|(_, v)| v)
}
fn insert(&mut self, key: K, value: V) -> Option<V> {
match self.entry(key) {
Entry::Occupied(mut entry) => Some(entry.insert(value)),
Entry::Vacant(entry) => {
entry.insert(value);
None
}
}
}
fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized,
{
let found = self
.iter_mut()
.enumerate()
.find(|(_, (k, _))| k.borrow() == key);
match found {
None => None,
Some((index, _)) => {
let (_, v) = self.swap_remove(index);
Some(v)
}
}
}
fn keys(&self) -> Keys<'_, K, V> {
Keys { inner: self.iter() }
}
fn into_keys(self) -> IntoKeys<K, V> {
IntoKeys {
inner: self.into_iter(),
}
}
fn values(&self) -> Values<'_, K, V> {
Values { inner: self.iter() }
}
fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
ValuesMut {
inner: self.iter_mut(),
}
}
fn into_values(self) -> IntoValues<K, V> {
IntoValues {
inner: self.into_iter(),
}
}
}
pub trait AssocStrictExt<K, V> {
fn entry(&mut self, key: K) -> Entry<K, V>;
fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized;
fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized;
fn insert(&mut self, key: K, value: V) -> Option<V>;
fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized;
fn keys(&self) -> Keys<'_, K, V>;
fn into_keys(self) -> IntoKeys<K, V>;
fn values(&self) -> Values<'_, K, V>;
fn values_mut(&mut self) -> ValuesMut<'_, K, V>;
fn into_values(self) -> IntoValues<K, V>;
}
impl<K, V> AssocStrictExt<K, V> for Vec<(K, V)>
where
K: Eq,
{
fn entry(&mut self, key: K) -> Entry<K, V> {
AssocExt::entry(self, key)
}
fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized,
{
AssocExt::get(self, key)
}
fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized,
{
AssocExt::get_mut(self, key)
}
fn insert(&mut self, key: K, value: V) -> Option<V> {
AssocExt::insert(self, key, value)
}
fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: PartialEq + ?Sized,
{
AssocExt::remove(self, key)
}
fn keys(&self) -> Keys<'_, K, V> {
AssocExt::keys(self)
}
fn into_keys(self) -> IntoKeys<K, V> {
AssocExt::into_keys(self)
}
fn values(&self) -> Values<'_, K, V> {
AssocExt::values(self)
}
fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
AssocExt::values_mut(self)
}
fn into_values(self) -> IntoValues<K, V> {
AssocExt::into_values(self)
}
}