deltoid/
option.rs

1//!
2
3use crate::{Apply, Core, Delta, DeltaResult, FromDelta, IntoDelta};
4use std::fmt::Debug;
5use serde::{Deserialize, Serialize};
6
7impl<T> Core for Option<T>
8where T: Clone + Debug + PartialEq + Core
9    + for<'de> Deserialize<'de>
10    + Serialize
11{
12    type Delta = OptionDelta<T>;
13}
14
15impl<T> Apply for Option<T>
16where T: Apply + FromDelta
17    + for<'de> Deserialize<'de>
18    + Serialize
19{
20    fn apply(&self, delta: Self::Delta) -> DeltaResult<Self> {
21        Ok(match (&self, delta) {
22            (None,    Self::Delta::None)    => None,
23            (Some(_), Self::Delta::None)    => self.clone(),
24            (None,    Self::Delta::Some(ref d)) => Some(
25                <T>::from_delta(d.clone(/*TODO: rm clone for more efficiency*/))?
26            ),
27            (Some(t), Self::Delta::Some(ref d)) =>
28                Some(t.apply(d.clone(/*TODO: rm clone for more efficiency*/))?),
29        })
30    }
31}
32
33impl<T> Delta for Option<T>
34where T: Delta + IntoDelta
35    + for<'de> Deserialize<'de>
36    + Serialize
37{
38    fn delta(&self, rhs: &Self) -> DeltaResult<Self::Delta> {
39        Ok(match (self, rhs) {
40            (Some(lhs), Some(rhs)) => Self::Delta::Some(lhs.delta(&rhs)?),
41            (None,      Some(rhs)) => Self::Delta::Some(rhs.clone().into_delta()?),
42            (Some(_),   None)      => Self::Delta::None,
43            (None,      None)      => Self::Delta::None,
44        })
45    }
46}
47
48impl<T> FromDelta for Option<T>
49where T: Clone + Debug + PartialEq + FromDelta
50    + for<'de> Deserialize<'de>
51    + Serialize
52{
53    fn from_delta(delta: <Self as Core>::Delta) -> DeltaResult<Self> {
54        Ok(match delta {
55            Self::Delta::None => None,
56            Self::Delta::Some(delta) => Some(<T>::from_delta(delta)?),
57        })
58    }
59}
60
61impl<T> IntoDelta for Option<T>
62where T: Clone + Debug + PartialEq + IntoDelta
63    + for<'de> Deserialize<'de>
64    + Serialize
65{
66    fn into_delta(self) -> DeltaResult<<Self as Core>::Delta> {
67        Ok(match self {
68            Self::None => OptionDelta::None,
69            Self::Some(t) => OptionDelta::Some(t.into_delta()?),
70        })
71    }
72}
73
74
75
76#[derive(Clone, PartialEq)]
77#[derive(serde_derive::Deserialize, serde_derive::Serialize)]
78pub enum OptionDelta<T: Core> {
79    None,
80    Some(<T as Core>::Delta),
81}
82
83impl<T: Core> std::fmt::Debug for OptionDelta<T> {
84    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
85        match &self {
86            Self::Some(d) => write!(f, "OptionDelta::Some({:#?})", d),
87            Self::None    => write!(f, "OptionDelta::None"),
88        }
89    }
90}
91
92
93#[allow(non_snake_case)]
94#[cfg(test)]
95mod tests {
96    use serde_json;
97    use super::*;
98
99    #[test]
100    fn Option__delta__same_values() -> DeltaResult<()> {
101        let foo = String::from("foo");
102        let bar = String::from("foo");
103        let option0 = Some(foo);
104        let option1 = Some(bar);
105        let delta: <Option<String> as Core>::Delta = option0.delta(&option1)?;
106        let json_string = serde_json::to_string(&delta)
107            .expect("Could not serialize to json");
108        println!("json_string: \"{}\"", json_string);
109        assert_eq!(json_string, "{\"Some\":\"foo\"}");
110        let delta1: <Option<String> as Core>::Delta = serde_json::from_str(
111            &json_string
112        ).expect("Could not deserialize from json");
113        assert_eq!(delta, delta1);
114        Ok(())
115    }
116
117    #[test]
118    fn Option__delta__different_values() -> DeltaResult<()> {
119        let foo = String::from("foo");
120        let bar = String::from("bar");
121        let option0 = Some(foo);
122        let option1 = Some(bar);
123        let delta: <Option<String> as Core>::Delta = option0.delta(&option1)?;
124        let json_string = serde_json::to_string(&delta)
125            .expect("Could not serialize to json");
126        println!("json_string: \"{}\"", json_string);
127        assert_eq!(json_string, "{\"Some\":\"bar\"}");
128        let delta1: <Option<String> as Core>::Delta = serde_json::from_str(
129            &json_string
130        ).expect("Could not deserialize from json");
131        assert_eq!(delta, delta1);
132        Ok(())
133    }
134
135    #[test]
136    fn Option__apply__same_values() -> DeltaResult<()> {
137        let foo = String::from("foo");
138        let bar = String::from("foo");
139        let option0 = Some(foo);
140        let option1 = Some(bar);
141        let delta: <Option<String> as Core>::Delta = option0.delta(&option1)?;
142        let option2 = option0.apply(delta)?;
143        assert_eq!(option1, option2);
144        Ok(())
145    }
146
147    #[test]
148    fn Option__apply__different_values() -> DeltaResult<()> {
149        let foo = String::from("foo");
150        let bar = String::from("bar");
151        let option0 = Some(foo);
152        let option1 = Some(bar);
153        let delta: <Option<String> as Core>::Delta = option0.delta(&option1)?;
154        let option2 = option0.apply(delta)?;
155        assert_eq!(option1, option2);
156        Ok(())
157    }
158}