use crate::{Token, generic_value::GenericValue, traits::DataSystem};
use std::{
collections::HashMap,
hash::{Hash, Hasher},
};
#[cfg(feature = "rkyv")]
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "D: Serialize, D::Animated: Serialize",
deserialize = "D: Deserialize<'de>, D::Animated: Deserialize<'de>"
))
)]
#[cfg_attr(feature = "rkyv", derive(Archive, RkyvSerialize, RkyvDeserialize))]
pub struct GenericTokenValueMap<D: DataSystem> {
attributes: HashMap<Token, GenericValue<D>>,
}
impl<D: DataSystem> Hash for GenericTokenValueMap<D> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.attributes.len().hash(state);
let mut items: Vec<_> = self.attributes.iter().collect();
items.sort_by_key(|(k, _)| *k);
for (token, value) in items {
token.hash(state);
value.hash(state);
}
}
}
impl<D: DataSystem> GenericTokenValueMap<D> {
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
attributes: HashMap::with_capacity(capacity),
}
}
pub fn insert(&mut self, token: impl Into<Token>, value: impl Into<GenericValue<D>>) {
self.attributes.insert(token.into(), value.into());
}
pub fn get(&self, token: &Token) -> Option<&GenericValue<D>> {
self.attributes.get(token)
}
pub fn get_mut(&mut self, token: &Token) -> Option<&mut GenericValue<D>> {
self.attributes.get_mut(token)
}
pub fn remove(&mut self, token: &Token) -> Option<GenericValue<D>> {
self.attributes.remove(token)
}
pub fn contains(&self, token: &Token) -> bool {
self.attributes.contains_key(token)
}
pub fn len(&self) -> usize {
self.attributes.len()
}
pub fn is_empty(&self) -> bool {
self.attributes.is_empty()
}
pub fn clear(&mut self) {
self.attributes.clear();
}
pub fn iter(&self) -> impl Iterator<Item = (&Token, &GenericValue<D>)> {
self.attributes.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&Token, &mut GenericValue<D>)> {
self.attributes.iter_mut()
}
pub fn tokens(&self) -> impl Iterator<Item = &Token> {
self.attributes.keys()
}
pub fn values(&self) -> impl Iterator<Item = &GenericValue<D>> {
self.attributes.values()
}
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut GenericValue<D>> {
self.attributes.values_mut()
}
pub fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = (Token, GenericValue<D>)>,
{
self.attributes.extend(iter);
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&Token, &GenericValue<D>) -> bool,
{
self.attributes.retain(|k, v| f(k, v));
}
}
impl<D: DataSystem> Eq for GenericTokenValueMap<D> {}
impl<D: DataSystem> Default for GenericTokenValueMap<D> {
fn default() -> Self {
Self {
attributes: HashMap::new(),
}
}
}
impl<D: DataSystem> FromIterator<(Token, GenericValue<D>)> for GenericTokenValueMap<D> {
fn from_iter<T: IntoIterator<Item = (Token, GenericValue<D>)>>(iter: T) -> Self {
Self {
attributes: HashMap::from_iter(iter),
}
}
}
impl<D: DataSystem, const N: usize> From<[(Token, GenericValue<D>); N]>
for GenericTokenValueMap<D>
{
fn from(arr: [(Token, GenericValue<D>); N]) -> Self {
Self {
attributes: HashMap::from(arr),
}
}
}