use alloc::collections::BTreeMap;
use core::marker::PhantomData;
use core::ops::Index;
use maplike::{
Assign, Clear, Container, Get, Insert, IntoIter, Len, Modify, Pop, Push, Remove, Set,
};
use crate::{ApplyDelta, UndoRedo, delta::Delta};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Recorder<
C: Container,
DC: Container = BTreeMap<<C as Container>::Key, <C as Container>::Value>,
> {
container: C,
delta: Delta<DC>,
}
impl<C: Container, DC: Container> AsRef<C> for Recorder<C, DC> {
#[inline]
fn as_ref(&self) -> &C {
&self.container
}
}
impl<C: Container, DC: Container + Default> Recorder<C, DC> {
#[inline]
pub fn new(container: C) -> Self {
Self::with_delta(container, Default::default())
}
}
impl<C: Container, DC: Container> Recorder<C, DC> {
#[inline]
pub fn with_delta(container: C, delta: Delta<DC>) -> Self {
Self { container, delta }
}
#[inline]
pub fn container(&self) -> &C {
&self.container
}
#[inline]
pub fn dissolve(self) -> (C, Delta<DC>) {
(self.container, self.delta)
}
}
impl<C: Container, DC: Container> Container for Recorder<C, DC> {
type Key = C::Key;
type Value = C::Value;
}
impl<C, DC> Assign<C> for Recorder<C, DC>
where
C: Assign + Clone,
DC: Get<usize, Value = C> + Set<usize>,
{
#[inline]
fn assign(&mut self, value: C) {
self.assign(value);
}
}
impl<C, DC> Recorder<C, DC>
where
C: Assign + Clone,
DC: Get<usize, Value = C> + Set<usize>,
{
#[inline]
pub fn assign(&mut self, value: C) {
if self.delta.inserted.get(&0).is_none() {
self.delta.removed.set(0, self.container.clone());
}
self.delta.inserted.set(0, value.clone());
self.container.assign(value);
}
}
impl<K, C, DC> Get<K> for Recorder<C, DC>
where
C: Get<K, Key = K>,
DC: Container,
{
#[inline]
fn get(&self, key: &K) -> Option<&C::Value> {
self.get(key)
}
}
impl<K, C, DC> Recorder<C, DC>
where
C: Get<K, Key = K>,
DC: Container,
{
#[inline]
pub fn get(&self, key: &K) -> Option<&C::Value> {
self.container.get(key)
}
}
impl<I, C, DC> Index<I> for Recorder<C, DC>
where
C: Container + Index<I, Output = C::Value>,
DC: Container,
{
type Output = C::Value;
#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.container[index]
}
}
impl<K, V, C, DC> Set<K> for Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Get<K> + Set<K>,
DC: Container<Key = K, Value = V> + Get<K> + Insert<K>,
K: Clone,
V: Clone,
{
#[inline]
fn set(&mut self, key: K, value: Self::Value) {
self.set(key, value);
}
}
impl<K, V, C, DC> Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Get<K> + Set<K>,
DC: Container<Key = K, Value = V> + Get<K> + Insert<K>,
K: Clone,
V: Clone,
{
#[inline]
pub fn set(&mut self, key: K, value: V) {
if self.delta.inserted.get(&key).is_none() {
if let Some(value_to_remove) = self.container.get(&key) {
self.delta
.removed
.insert(key.clone(), value_to_remove.clone());
}
}
self.delta.inserted.insert(key.clone(), value.clone());
self.container.set(key, value);
}
}
impl<K, V, C, DC> Modify<K> for Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Get<K> + Modify<K>,
DC: Container<Key = K, Value = V> + Get<K> + Insert<K>,
K: Clone,
V: Clone,
{
#[inline]
fn modify<F>(&mut self, key: K, f: F)
where
F: FnOnce(&mut Self::Value),
{
self.modify(key, f);
}
}
impl<K, V, C, DC> Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Get<K> + Modify<K>,
DC: Container<Key = K, Value = V> + Get<K> + Insert<K>,
K: Clone,
V: Clone,
{
#[inline]
pub fn modify<F>(&mut self, key: K, f: F)
where
F: FnOnce(&mut V),
{
if self.delta.inserted.get(&key).is_none() {
if let Some(value_to_remove) = self.container.get(&key) {
self.delta
.removed
.insert(key.clone(), value_to_remove.clone());
}
}
self.container.modify(key.clone(), f);
if let Some(value) = self.container.get(&key) {
self.delta.inserted.insert(key, value.clone());
}
}
}
impl<K, V, C, DC> Insert<K> for Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Get<K> + Insert<K>,
DC: Container<Key = K, Value = V> + Get<K> + Insert<K>,
K: Clone,
V: Clone,
{
#[inline]
fn insert(&mut self, key: K, value: V) {
self.insert(key, value)
}
}
impl<K, V, C, DC> Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Get<K> + Insert<K>,
DC: Container<Key = K, Value = V> + Get<K> + Insert<K>,
K: Clone,
V: Clone,
{
#[inline]
pub fn insert(&mut self, key: K, value: V) {
if self.delta.inserted.get(&key).is_none() {
if let Some(value_to_remove) = self.container.get(&key) {
self.delta
.removed
.insert(key.clone(), value_to_remove.clone());
}
}
self.delta.inserted.insert(key.clone(), value.clone());
self.container.insert(key, value.clone());
}
}
impl<K, V, C, DC> Remove<K> for Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Remove<K>,
DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>,
K: Clone,
V: Clone,
{
#[inline]
fn remove(&mut self, key: &K) -> Option<V> {
self.remove(key)
}
}
impl<K, V, C, DC> Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Remove<K>,
DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>,
K: Clone,
V: Clone,
{
#[inline]
pub fn remove(&mut self, key: &K) -> Option<V> {
let value = self.container.remove(key)?;
if self.delta.inserted.remove(key).is_none() {
self.delta.removed.insert(key.clone(), value.clone());
}
Some(value)
}
}
impl<K, V, C, DC> Push<K> for Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Push<K>,
DC: Container<Key = K, Value = V> + Insert<K>,
K: Clone,
V: Clone,
{
#[inline]
fn push(&mut self, value: V) -> K {
self.push(value)
}
}
impl<K, V, C, DC> Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Push<K>,
DC: Container<Key = K, Value = V> + Insert<K>,
K: Clone,
V: Clone,
{
#[inline]
pub fn push(&mut self, value: V) -> K {
let key = self.container.push(value.clone());
self.delta.inserted.insert(key.clone(), value);
key
}
}
impl<K, V, C, DC> Pop for Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Len + Pop,
DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>,
K: Clone,
V: Clone,
{
#[inline]
fn pop(&mut self) -> Option<V> {
self.pop()
}
}
impl<K, V, C, DC> Recorder<C, DC>
where
C: Container<Key = K, Value = V> + Len + Pop,
DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>,
K: Clone,
V: Clone,
{
#[inline]
pub fn pop(&mut self) -> Option<V> {
let value = self.container.pop()?;
if self.delta.inserted.remove(&self.container.len()).is_none() {
self.delta
.removed
.insert(self.container.len(), value.clone());
}
Some(value)
}
}
impl<K, V, C, DC> Clear for Recorder<C, DC>
where
C: Clear + Clone + IntoIter<K, Value = V>,
DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>,
{
#[inline]
fn clear(&mut self) {
self.clear();
}
}
impl<K, V, C, DC> Recorder<C, DC>
where
C: Clear + Clone + IntoIter<K, Value = V>,
DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>,
{
pub fn clear(&mut self) {
for (key, value) in self.container.clone().into_iter() {
self.delta.removed.insert(key, value);
}
self.container.clear();
}
}
impl<C, DC> Len for Recorder<C, DC>
where
C: Len,
DC: Container,
{
#[inline]
fn len(&self) -> C::Key {
self.len()
}
}
impl<C, DC> Recorder<C, DC>
where
C: Len,
DC: Container,
{
#[inline]
fn len(&self) -> C::Key {
self.container.len()
}
}
impl<K, C, DC> IntoIter<K> for Recorder<C, DC>
where
C: IntoIter<K>,
DC: Container,
{
type IntoIter = C::IntoIter;
#[inline]
fn into_iter(self) -> C::IntoIter {
self.container.into_iter()
}
}
impl<
C: Container + ApplyDelta<DC>,
RDC: Container,
DC: IntoIter<C::Key> + Container<Key = C::Key, Value = C::Value>,
> ApplyDelta<DC> for Recorder<C, RDC>
{
#[inline]
fn apply_delta(&mut self, delta: Delta<DC>) {
self.container.apply_delta(delta)
}
}
pub trait FlushDelta<DC> {
fn flush_delta(&mut self) -> Delta<DC>;
}
impl<C: Container, DC: Container + Default> FlushDelta<DC> for Recorder<C, DC> {
#[inline]
fn flush_delta(&mut self) -> Delta<DC> {
self.flush_delta()
}
}
impl<C, DC> FlushDelta<Recorder<C, DC>> for Recorder<C, DC>
where
C: Container + Default + ApplyDelta<DC>,
DC: Container + Default,
{
#[inline]
fn flush_delta(&mut self) -> Delta<Recorder<C, DC>> {
let (removed, inserted) = <Recorder<C, DC> as FlushDelta<DC>>::flush_delta(self).dissolve();
let mut removed_container = C::default();
removed_container.apply_delta(Delta::with_removed_inserted(DC::default(), removed));
let mut inserted_container = C::default();
inserted_container.apply_delta(Delta::with_removed_inserted(DC::default(), inserted));
Delta::with_removed_inserted(
Recorder::new(removed_container),
Recorder::new(inserted_container),
)
}
}
impl<C: Container, DC: Container + Default> Recorder<C, DC> {
#[inline]
pub fn flush_delta(&mut self) -> Delta<DC> {
core::mem::replace(&mut self.delta, Delta::new())
}
}
impl<V, DC: Default> FlushDelta<DC> for PhantomData<V> {
#[inline]
fn flush_delta(&mut self) -> Delta<DC> {
Delta::default()
}
}
impl<Cmd, DC: Container + Default> UndoRedo<Delta<DC>, Cmd> {
pub fn edit<
K,
V,
C: Container<Key = K, Value = V> + Get<K>,
F: FnOnce(&mut Recorder<C, DC>) -> Cmd,
>(
&mut self,
container: C,
f: F,
) -> C
where
DC: Container<Key = K, Value = V>,
K: Clone,
V: Clone,
{
let mut recorder = Recorder::<C, DC>::new(container);
let cmd = f(&mut recorder);
let (container, delta) = recorder.dissolve();
self.cmd_commit(cmd, delta);
container
}
}