#![no_std]
#![deny(missing_docs)]
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(feature = "serde")]
use serde::ser::{Serialize, Serializer, SerializeMap};
#[cfg(feature = "serde")]
use serde::de::{self, Deserialize, Deserializer, Error, MapAccess};
#[cfg(feature = "serde")]
use core::fmt;
use core::hash::{Hash, Hasher};
use core::iter::Enumerate;
use core::marker::PhantomData;
use core::ops::{Index, IndexMut};
use core::slice;
mod implementations;
#[doc(hidden)]
pub trait Internal<V>: Sized {
type Array;
fn slice(&Self::Array) -> &[V];
fn slice_mut(&mut Self::Array) -> &mut [V];
fn from_usize(usize) -> Self;
fn to_usize(self) -> usize;
fn from_function<F: FnMut(Self) -> V>(F) -> Self::Array;
}
#[derive(Debug)]
pub struct EnumMap<K: Internal<V>, V> {
array: K::Array,
}
impl<K: Internal<V>, V> EnumMap<K, V> {
pub fn len(&self) -> usize {
K::slice(&self.array).len()
}
pub fn is_empty(&self) -> bool {
K::slice(&self.array).is_empty()
}
pub fn iter(&self) -> Iter<K, V> {
self.into_iter()
}
pub fn iter_mut(&mut self) -> IterMut<K, V> {
self.into_iter()
}
}
impl<F: FnMut(K) -> V, K: Internal<V>, V> From<F> for EnumMap<K, V> {
fn from(f: F) -> Self {
EnumMap { array: K::from_function(f) }
}
}
#[macro_export]
macro_rules! enum_map {
{$($t:tt)*} => {
::enum_map::EnumMap::from(|k| match k { $($t)* })
};
}
impl<K: Internal<V>, V: Default> EnumMap<K, V>
where K::Array: Default
{
pub fn new() -> Self {
EnumMap::default()
}
}
impl<K: Internal<V>, V> Clone for EnumMap<K, V>
where K::Array: Clone
{
fn clone(&self) -> Self {
EnumMap { array: self.array.clone() }
}
}
impl<K: Internal<V>, V> Copy for EnumMap<K, V> where K::Array: Copy {}
impl<K: Internal<V>, V> PartialEq for EnumMap<K, V>
where K::Array: PartialEq
{
fn eq(&self, other: &Self) -> bool {
self.array == other.array
}
}
impl<K: Internal<V>, V> Eq for EnumMap<K, V> where K::Array: Eq {}
impl<K: Internal<V>, V> Hash for EnumMap<K, V>
where K::Array: Hash
{
fn hash<H: Hasher>(&self, state: &mut H) {
self.array.hash(state);
}
}
impl<K: Internal<V>, V> Default for EnumMap<K, V>
where K::Array: Default
{
fn default() -> Self {
EnumMap { array: K::Array::default() }
}
}
impl<K: Internal<V>, V> Index<K> for EnumMap<K, V> {
type Output = V;
fn index(&self, key: K) -> &V {
&K::slice(&self.array)[key.to_usize()]
}
}
impl<K: Internal<V>, V> IndexMut<K> for EnumMap<K, V> {
fn index_mut(&mut self, key: K) -> &mut V {
&mut K::slice_mut(&mut self.array)[key.to_usize()]
}
}
pub struct Iter<'a, K, V: 'a> {
_phantom: PhantomData<K>,
iterator: Enumerate<slice::Iter<'a, V>>,
}
impl<'a, K: Internal<V>, V> Iterator for Iter<'a, K, V> {
type Item = (K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.iterator
.next()
.map(|(index, item)| (K::from_usize(index), item))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iterator.size_hint()
}
}
impl<'a, K: Internal<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.iterator
.next_back()
.map(|(index, item)| (K::from_usize(index), item))
}
}
impl<'a, K: Internal<V>, V> ExactSizeIterator for Iter<'a, K, V> {}
impl<'a, K: Internal<V>, V> IntoIterator for &'a EnumMap<K, V> {
type Item = (K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
Iter {
_phantom: PhantomData,
iterator: K::slice(&self.array).iter().enumerate(),
}
}
}
pub struct IterMut<'a, K, V: 'a> {
_phantom: PhantomData<K>,
iterator: Enumerate<slice::IterMut<'a, V>>,
}
impl<'a, K: Internal<V>, V> Iterator for IterMut<'a, K, V> {
type Item = (K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
self.iterator
.next()
.map(|(index, item)| (K::from_usize(index), item))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iterator.size_hint()
}
}
impl<'a, K: Internal<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.iterator
.next_back()
.map(|(index, item)| (K::from_usize(index), item))
}
}
impl<'a, K: Internal<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}
impl<'a, K: Internal<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
type Item = (K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
IterMut {
_phantom: PhantomData,
iterator: K::slice_mut(&mut self.array).iter_mut().enumerate(),
}
}
}
#[cfg(feature = "serde")]
impl<K: Internal<V> + Serialize, V: Serialize> Serialize for EnumMap<K, V> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut map = serializer.serialize_map(Some(self.len()))?;
for (key, value) in self {
map.serialize_entry(&key, value)?;
}
map.end()
}
}
#[cfg(feature = "serde")]
impl<'de, K, V> Deserialize<'de> for EnumMap<K, V>
where K: Internal<V> + Internal<Option<V>> + Deserialize<'de>,
V: Deserialize<'de>
{
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_map(Visitor(PhantomData))
}
}
#[cfg(feature = "serde")]
struct Visitor<K: Internal<V>, V>(PhantomData<EnumMap<K, V>>);
#[cfg(feature = "serde")]
impl<'de, K, V> de::Visitor<'de> for Visitor<K, V>
where K: Internal<V> + Internal<Option<V>> + Deserialize<'de>,
V: Deserialize<'de>
{
type Value = EnumMap<K, V>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "map")
}
fn visit_map<M: MapAccess<'de>>(self, mut access: M) -> Result<Self::Value, M::Error> {
let mut entries = EnumMap::from(|_| None);
while let Some((key, value)) = access.next_entry()? {
entries[key] = Some(value);
}
for (_, value) in &entries {
if value.is_none() {
return Err(M::Error::custom("key not specified"));
}
}
Ok(EnumMap::from(|key| entries[key].take().unwrap()))
}
}