use crate::prelude::*;
use std::fmt::Debug;
pub struct Store<T>(ArenaHandle<T>);
impl<T> Copy for Store<T> {}
impl<T> Clone for Store<T> {
fn clone(&self) -> Self { *self }
}
impl<T: 'static + Send + Default> Default for Store<T> {
fn default() -> Self { Self::new(T::default()) }
}
impl<T: 'static + Send> Store<T> {
pub fn new(val: T) -> Self { Self(Arena::insert(val)) }
pub fn get(&self) -> T
where
T: Clone,
{
self.0.with(|val| val.clone())
}
pub fn set(&self, value: T) { self.0.with_mut(|val| *val = value); }
pub fn with<F, R>(&self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
self.0.with(f)
}
pub fn remove(&self) { self.0.remove(); }
}
impl<T: 'static + Debug> Debug for Store<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.with(|val| write!(f, "Store({:?})", val))
}
}
impl<T: 'static + Send> Store<Vec<T>> {
pub fn new_vec() -> Self { Self::default() }
pub fn push(&self, value: T) { self.0.with_mut(|vec| vec.push(value)); }
pub fn pop(&self) -> Option<T> { self.0.with_mut(|vec| vec.pop()) }
pub fn clear(&self) { self.0.with_mut(|vec| vec.clear()); }
pub fn len(&self) -> usize { self.0.with(|vec| vec.len()) }
pub fn is_empty(&self) -> bool { self.0.with(|vec| vec.is_empty()) }
pub fn get_index(&self, index: usize) -> Option<T>
where
T: Clone,
{
self.0.with(|vec| vec.get(index).cloned())
}
}
#[cfg(test)]
mod test {
use crate::prelude::*;
#[test]
fn works() {
let store = Store::new(0);
store.get().xpect_eq(0);
store.set(1);
store.get().xpect_eq(1);
}
#[test]
fn vec() {
let store = Store::<Vec<u32>>::default();
store.len().xpect_eq(0);
store.push(1);
store.len().xpect_eq(1);
store.push(2);
store.len().xpect_eq(2);
store.pop();
store.len().xpect_eq(1);
store.clear();
store.len().xpect_eq(0);
}
#[test]
fn get_index() {
let store = Store::<Vec<u32>>::default();
store.push(10);
store.push(20);
store.get_index(0).xpect_eq(Some(10));
store.get_index(1).xpect_eq(Some(20));
store.get_index(2).xpect_none();
}
}