1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//!

// TODO:
// Can a delta be applied to a value of:
//   + an array type i.e. [T, N]?             (Probably yes)
//   + a slice type  e.g. &[T]  and  &str?    (Very unlikely for borrowed types)

#[macro_use] pub mod snapshot;
pub mod borrow;
pub mod boxed;
pub mod collections;
pub mod convert;
#[macro_use] pub mod error;
pub mod option;
pub mod range;
pub mod rc;
pub mod string;
pub mod sync;
pub mod tuple;
pub mod vec;


pub use crate::borrow::CowDelta;
pub use crate::boxed::*;
pub use crate::collections::*;
pub use crate::convert::{FromDelta, IntoDelta};
pub use crate::error::{DeltaError, DeltaResult};
pub use crate::option::{OptionDelta};
pub use crate::range::RangeDelta;
pub use crate::rc::*;
pub use crate::string::StringDelta;
pub use crate::sync::*;
pub use crate::tuple::*;
pub use crate::vec::{EltDelta, VecDelta};
use serde::{Deserialize, Serialize};


#[allow(type_alias_bounds)]
pub type Delta<T: Deltoid> = <T as Deltoid>::Delta;


/// Definitions for delta operations.
pub trait Deltoid: Sized + PartialEq + Clone + std::fmt::Debug {
    type Delta: Clone + std::fmt::Debug + PartialEq
        + Serialize
        + for<'de> Deserialize<'de>;

    /// Calculate a new instance of `Self` based on `self` and
    /// `delta` i.e. calculate `self --[delta]--> other`.
    ///                                           ^^^^^
    fn apply_delta(&self, delta: &Self::Delta) -> DeltaResult<Self>;

    /// Calculate `self --[delta]--> other`.
    ///                    ^^^^^
    fn delta(&self, other: &Self) -> DeltaResult<Self::Delta>;

    /// Calculate `other --[delta]--> self`.
    ///                     ^^^^^
    fn inverse_delta(&self, other: &Self) -> DeltaResult<Self::Delta> {
        other.delta(self)
    }
}


macro_rules! impl_delta_trait_for_primitive_types {
    ( $($type:ty => $delta:ident $(, derive $($traits:ident),+)?);* $(;)? ) => {
        $(
            impl Deltoid for $type {
                type Delta = $delta;

                fn apply_delta(&self, delta: &Self::Delta) -> DeltaResult<Self> {
                    Self::from_delta(delta.clone())
                }

                fn delta(&self, rhs: &Self) -> DeltaResult<Self::Delta> {
                    rhs.clone().into_delta()
                }
            }

            $( #[derive( $($traits),+ )] )?
            #[derive(serde_derive::Deserialize, serde_derive::Serialize)]
            pub struct $delta(Option<$type>);

            impl IntoDelta for $type {
                fn into_delta(self) -> DeltaResult<<Self as Deltoid>::Delta> {
                    Ok($delta(Some(self)))
                }
            }

            impl FromDelta for $type {
                fn from_delta(delta: <Self as Deltoid>::Delta) -> DeltaResult<Self> {
                    delta.0.ok_or(DeltaError::ExpectedValue)
                }
            }
        )*
    };
}

impl_delta_trait_for_primitive_types! {
    i8    => I8Delta,    derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    i16   => I16Delta,   derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    i32   => I32Delta,   derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    i64   => I64Delta,   derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    i128  => I128Delt,   derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    isize => IsizeDelta, derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;

    u8    => U8Delta,    derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    u16   => U16Delta,   derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    u32   => U32Delta,   derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    u64   => U64Delta,   derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    u128  => U128Delta,  derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    usize => UsizeDelta, derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;

    f32   => F32Delta,   derive Clone, Debug, PartialEq, PartialOrd;
    f64   => F64Delta,   derive Clone, Debug, PartialEq, PartialOrd;
    bool  => BoolDelta,  derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    char  => CharDelta,  derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
    ()    => UnitDelta,  derive Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash;
}