use crate::utils::strings::{AllCharsTrait, CharType};
use std::collections::hash_map::Entry;
use std::hash::Hash;
use ahash::HashMap;
pub trait StateField {
fn push_stack(&mut self);
fn pop_stack(&mut self);
}
#[derive(Default)]
pub struct SingleValueField<V>(V,Vec<Option<V>>);
impl<V> SingleValueField<V> {
pub fn new(initial:V) -> Self { SingleValueField(initial,Vec::new()) }
pub fn get(&self) -> &V { &self.0 }
pub fn set_locally(&mut self,v:V) {
if let Some(ov) = self.1.last_mut() {
match ov {
ov@None => {
let old = std::mem::replace(&mut self.0,v);
*ov = Some(old)
}
_ => self.0 = v
}
} else {
self.0 = v
}
}
pub fn set_globally(&mut self,v:V) {
self.0 = v;
for ov in self.1.iter_mut() {
*ov = None
}
}
}
impl<V> StateField for SingleValueField<V> {
fn push_stack(&mut self) { self.1.push(None) }
fn pop_stack(&mut self) {
if let Some(Some(v)) = self.1.pop() {
self.0 = v
}
}
}
pub trait KeyValueField<K,V>: StateField {
fn get(&self,k:&K) -> V;
fn set_locally(&mut self,k:K,v:V);
fn set_globally(&mut self,k:K,v:V);
}
pub struct CharField<C:CharType,A:Clone+Default>{pub charfield: C::Allchars<A>, changes: Vec<HashMap<C,A>>}
impl<C:CharType,A:Clone+Default> StateField for CharField<C,A> {
fn push_stack(&mut self) { self.changes.push(HashMap::default()) }
fn pop_stack(&mut self) {
if let Some(m) = self.changes.pop() {
for (k,v) in m {
self.charfield.set(k,v)
}
}
}
}
impl<C:CharType,A:Clone+Default> KeyValueField<C,A> for CharField<C,A> {
fn get(&self, c:&C) -> A { self.charfield.get(*c).clone() }
fn set_locally(&mut self, k: C, v:A) {
if let Some(m) = self.changes.last_mut() {
match m.entry(k) {
Entry::Vacant(e) => {
e.insert(self.charfield.replace(k,v));
}
Entry::Occupied(_) => {
self.charfield.set(k,v);
}
}
} else {
self.charfield.set(k,v);
}
}
fn set_globally(&mut self, k: C, v:A) {
self.charfield.set(k,v);
for ov in self.changes.iter_mut() {
ov.remove(&k);
}
}
}
impl<C:CharType,A:Clone+Default> CharField<C,A> {
pub fn new(initial: C::Allchars<A>) -> Self { CharField{charfield:initial, changes:Vec::new()} }
}
pub struct VecField<V:Default>(Vec<V>, Vec<HashMap<usize,V>>);
impl<V:Default+Clone> VecField<V> {
pub fn new() -> Self { VecField(Vec::with_capacity(255), Vec::new()) }
fn set_inner(vec:&mut Vec<V>,k:usize,v:V) -> Option<V> {
if k < vec.len() {
Some(std::mem::replace(&mut vec[k],v))
} else {
vec.resize(k+1,V::default());
vec[k] = v;
None
}
}
}
impl<V:Default+Clone> StateField for VecField<V> {
fn push_stack(&mut self) { self.1.push(HashMap::default()) }
fn pop_stack(&mut self) {
if let Some(m) = self.1.pop() {
for (k,v) in m {
Self::set_inner(&mut self.0,k,v);
}
}
}
}
impl<V:Default+Clone> KeyValueField<usize,V> for VecField<V> {
fn get(&self, k: &usize) -> V {
if *k < self.0.len() {
self.0[*k].clone()
} else {
V::default()
}
}
fn set_locally(&mut self, k: usize, v: V) {
if let Some(m) = self.1.last_mut() {
match m.entry(k) {
Entry::Vacant(e) => {
e.insert(match Self::set_inner(&mut self.0,k,v) {
Some(old) => old,
None => V::default()
});
}
Entry::Occupied(_) => {
Self::set_inner(&mut self.0,k,v);
}
}
} else {
Self::set_inner(&mut self.0,k,v);
}
}
fn set_globally(&mut self, k: usize, v: V) {
Self::set_inner(&mut self.0,k,v);
for ov in self.1.iter_mut() {
ov.remove(&k);
}
}
}
pub trait IsDefault:Default {
fn is_default(&self) -> bool;
}
impl IsDefault for usize {
fn is_default(&self) -> bool { *self == 0 }
}
impl IsDefault for u8 {
fn is_default(&self) -> bool { *self == 0 }
}
impl IsDefault for i32 {
fn is_default(&self) -> bool { *self == 0 }
}
impl<A> IsDefault for Option<A> {
fn is_default(&self) -> bool { self.is_none() }
}
impl<A> IsDefault for Vec<A> {
fn is_default(&self) -> bool { self.is_empty() }
}
pub struct HashMapField<K:Eq+Hash+Clone,V:Default+Clone+IsDefault>(HashMap<K,V>, Vec<HashMap<K,V>>);
impl<K:Eq+Hash+Clone,V:Default+Clone+IsDefault> HashMapField<K,V> {
pub fn new() -> Self { HashMapField(HashMap::default(), Vec::new()) }
pub fn set_i(map:&mut HashMap<K,V>, k: K, v: V) -> Option<V> {
if v.is_default() {
map.remove(&k)
} else {
map.insert(k,v)
}
}
}
impl<K:Eq+Hash+Clone,V:Default+Clone+IsDefault> StateField for HashMapField<K,V> {
fn push_stack(&mut self) { self.1.push(HashMap::default()) }
fn pop_stack(&mut self) {
if let Some(m) = self.1.pop() {
for (k,v) in m {
Self::set_i(&mut self.0,k,v);
}
}
}
}
impl<K:Eq+Hash+Clone,V:Default+Clone+IsDefault> KeyValueField<K,V> for HashMapField<K,V> {
fn get(&self, k: &K) -> V {
match self.0.get(k) {
Some(v) => v.clone(),
_ => V::default()
}
}
fn set_locally(&mut self, k: K, v: V) {
if let Some(m) = self.1.last_mut() {
match m.entry(k.clone()) {
Entry::Vacant(e) => {
e.insert(Self::set_i(&mut self.0,k,v).unwrap_or_default());
}
Entry::Occupied(_) => {
Self::set_i(&mut self.0,k,v);
}
}
} else {
Self::set_i(&mut self.0,k,v);
}
}
fn set_globally(&mut self, k: K, v: V) {
for ov in self.1.iter_mut() {
ov.remove(&k);
}
Self::set_i(&mut self.0,k,v);
}
}