use crate::DeltaStruct;
use paste::paste;
use std::{
collections::{HashMap, HashSet},
hash::Hash,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
macro_rules! impl_num {
($($tname:ty),*) => {
$(paste! {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(non_camel_case_types)]
#[derive(Clone)]
pub enum [<$tname Delta>] {
Set($tname),
Add($tname),
Sub($tname),
Mult($tname),
Div($tname),
Mod($tname),
}
impl DeltaStruct<[<$tname Delta>]> for $tname {
fn apply(&mut self, delta : &[<$tname Delta>]) {
match delta {
[<$tname Delta>]::Set(x) => { *self = *x }
[<$tname Delta>]::Add(x) => { *self += *x }
[<$tname Delta>]::Sub(x) => { *self -= *x }
[<$tname Delta>]::Mult(x) => { *self *= *x }
[<$tname Delta>]::Div(x) => { *self /= *x }
[<$tname Delta>]::Mod(x) => { *self %= *x }
}
}
}
})*
}
}
impl_num!(i8, i16, i32, i64, u8, u16, u32, u64, usize, isize, f32, f64);
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(non_camel_case_types)]
#[derive(Clone)]
pub enum boolDelta {
Set(bool),
Toggle,
}
impl DeltaStruct<boolDelta> for bool {
fn apply(&mut self, delta: &boolDelta) {
match delta {
boolDelta::Set(x) => *self = *x,
boolDelta::Toggle => *self = !*self,
}
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[allow(non_camel_case_types)]
#[derive(Clone)]
pub enum charDelta {
Set(char),
}
impl DeltaStruct<charDelta> for char {
fn apply(&mut self, delta: &charDelta) {
match delta {
charDelta::Set(x) => *self = *x,
}
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub enum StringDelta {
Set(String),
Append(String),
}
impl DeltaStruct<StringDelta> for String {
fn apply(&mut self, delta: &StringDelta) {
match delta {
StringDelta::Set(x) => *self = x.clone(),
StringDelta::Append(x) => *self += x,
}
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub enum VecDelta<T>
where
T: Clone,
{
Set(Vec<T>),
Push(T),
Pop(),
}
impl<T> DeltaStruct<VecDelta<T>> for Vec<T>
where
T: Clone,
{
fn apply(&mut self, delta: &VecDelta<T>) {
match delta {
VecDelta::Set(x) => *self = x.clone(),
VecDelta::Push(x) => self.push(x.clone()),
VecDelta::Pop() => {
self.pop();
}
}
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub enum OptionDelta<T>
where
T: Clone,
{
Set(T),
Clear,
}
impl<T> DeltaStruct<OptionDelta<T>> for Option<T>
where
T: Clone,
{
fn apply(&mut self, delta: &OptionDelta<T>) {
match delta {
OptionDelta::Set(x) => *self = Some(x.clone()),
OptionDelta::Clear => *self = None,
}
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub enum HashSetDelta<T>
where
T: Clone + Eq + Hash,
{
Set(HashSet<T>),
Insert(T),
Remove(T),
}
impl<T> DeltaStruct<HashSetDelta<T>> for HashSet<T>
where
T: Clone + Eq + Hash,
{
fn apply(&mut self, delta: &HashSetDelta<T>) {
match delta {
HashSetDelta::Set(x) => *self = x.clone(),
HashSetDelta::Insert(x) => {
self.insert(x.clone());
}
HashSetDelta::Remove(x) => {
self.remove(x);
}
}
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub enum HashMapDelta<T, U>
where
T: Clone + Eq + Hash,
U: Clone,
{
Set(HashMap<T, U>),
Insert(T, U),
Remove(T),
}
impl<T, U> DeltaStruct<HashMapDelta<T, U>> for HashMap<T, U>
where
T: Clone + Eq + Hash,
U: Clone,
{
fn apply(&mut self, delta: &HashMapDelta<T, U>) {
match delta {
HashMapDelta::Set(x) => *self = x.clone(),
HashMapDelta::Insert(k, v) => {
self.insert(k.clone(), v.clone());
}
HashMapDelta::Remove(k) => {
self.remove(k);
}
}
}
}