deltoid/sync/
rwlock.rs

1//! A newtype wrapping [`RwLock`] that provides extra functionality in
2//! the form of delta support, de/serialization, partial equality and more.
3//!
4//! [`RwLock`]: https://doc.rust-lang.org/std/sync/struct.RwLock.html
5
6use crate::{Apply, Core, Delta, DeltaError, DeltaResult, FromDelta, IntoDelta};
7use serde::{Serialize, Serializer, Deserialize, Deserializer};
8use serde::de::Visitor;
9use std::cmp::Ordering;
10use std::fmt::{self, Debug};
11use std::hash::{Hash, Hasher};
12use std::marker::PhantomData;
13pub use std::sync::{LockResult, RwLockReadGuard, RwLockWriteGuard};
14
15
16#[derive(Debug, Default)]
17pub struct RwLock<T>(std::sync::RwLock<T>);
18
19#[allow(unused)]
20impl<T> RwLock<T> {
21    pub fn new(thing: T) -> Self { Self(std::sync::RwLock::new(thing)) }
22
23    pub fn into_inner(self) -> LockResult<T> { self.0.into_inner() }
24
25    pub fn try_read(&self) -> DeltaResult<RwLockReadGuard<T>> {
26        self.0.try_read().map_err(DeltaError::from)
27    }
28
29    pub fn try_write(&self) -> DeltaResult<RwLockWriteGuard<T>> {
30        self.0.try_write().map_err(DeltaError::from)
31    }
32}
33
34impl<T: Clone> Clone for RwLock<T> {
35    fn clone(&self) -> Self {
36        let value: &T = &*self.try_read().unwrap();
37        Self::new(value.clone())
38    }
39}
40
41impl<T: Hash> Hash for RwLock<T> {
42    fn hash<H: Hasher>(&self, state: &mut H) {
43        self.try_read().unwrap().hash(state)
44    }
45}
46
47impl<T: PartialEq> PartialEq for RwLock<T> {
48    fn eq(&self, rhs: &Self) -> bool {
49        let lhs: &T = &*self.0.try_read().unwrap();
50        let rhs: &T = &*rhs.0.try_read().unwrap();
51        lhs.eq(rhs)
52    }
53}
54
55impl<T: Eq> Eq for RwLock<T> { }
56
57impl<T: PartialOrd> PartialOrd for RwLock<T> {
58    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
59        let lhs: &T = &*self.0.try_read().unwrap();
60        let rhs: &T = &*rhs.0.try_read().unwrap();
61        lhs.partial_cmp(rhs)
62    }
63}
64
65impl<T: Ord> Ord for RwLock<T> {
66    fn cmp(&self, rhs: &Self) -> Ordering {
67        let lhs: &T = &*self.0.try_read().unwrap();
68        let rhs: &T = &*rhs.0.try_read().unwrap();
69        lhs.cmp(rhs)
70    }
71}
72
73
74impl<T: Serialize> Serialize for RwLock<T> {
75    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
76        let value: &T = &self.0.try_read().unwrap(/*TODO*/);
77        serializer.serialize_newtype_struct("RwLock", value)
78    }
79}
80
81impl<'de, T: Deserialize<'de>> Deserialize<'de> for RwLock<T> {
82    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83    where D: Deserializer<'de> {
84        struct RwLockVisitor<V>(PhantomData<V>);
85
86        impl<'de, V: Deserialize<'de>> Visitor<'de> for RwLockVisitor<V> {
87            type Value = RwLock<V>;
88
89            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
90                formatter.write_str("struct RwLock<T>")
91            }
92
93            fn visit_newtype_struct<D: Deserializer<'de>>(
94                self,
95                deserializer: D
96            ) -> Result<Self::Value, D::Error> {
97                Deserialize::deserialize(deserializer).map(RwLock::new)
98            }
99        }
100
101        deserializer.deserialize_newtype_struct(
102            "RwLock",
103            RwLockVisitor(PhantomData)
104        )
105    }
106}
107
108
109
110impl<T> Core for RwLock<T>
111where T: Clone + Debug + PartialEq + Core
112    + for<'de> Deserialize<'de>
113    + Serialize
114{
115    type Delta = RwLockDelta<T>;
116}
117
118impl<T> Apply for RwLock<T>
119where T: Clone + Debug + PartialEq + Apply
120    + for<'de> Deserialize<'de>
121    + Serialize
122{
123    fn apply(&self, delta: Self::Delta) -> DeltaResult<Self> {
124        let lhs: &T = &*self.0.try_read().unwrap(/*TODO*/);
125        match delta.0 {
126            Some(delta) => lhs.apply(delta).map(Self::new),
127            None => Ok(Self::new(lhs.clone())),
128        }
129    }
130}
131
132impl<T> Delta for RwLock<T>
133where T: Clone + Debug + PartialEq + Delta
134    + for<'de> Deserialize<'de>
135    + Serialize
136{
137    fn delta(&self, rhs: &Self) -> DeltaResult<Self::Delta> {
138        let lhs: &T = &*self.0.try_read().unwrap(/*TODO*/);
139        let rhs: &T = &*rhs.0.try_read().unwrap(/*TODO*/);
140        lhs.delta(rhs).map(Some).map(RwLockDelta)
141    }
142}
143
144impl<T> FromDelta for RwLock<T>
145where T: Clone + Debug + PartialEq + FromDelta
146    + for<'de> Deserialize<'de>
147    + Serialize
148{
149    fn from_delta(delta: Self::Delta) -> DeltaResult<Self> {
150        let delta = delta.0.ok_or_else(|| ExpectedValue!("RwLockDelta<T>"))?;
151        <T>::from_delta(delta).map(Self::new)
152    }
153}
154
155impl<T> IntoDelta for RwLock<T>
156where T: Clone + Debug + PartialEq + IntoDelta
157    + for<'de> Deserialize<'de>
158    + Serialize
159{
160    fn into_delta(self) -> DeltaResult<Self::Delta> {
161        let value: &T = &*self.0.try_read().unwrap(/*TODO*/);
162        value.clone().into_delta().map(Some).map(RwLockDelta)
163    }
164}
165
166
167
168
169#[derive(Clone, PartialEq)]
170#[derive(serde_derive::Deserialize, serde_derive::Serialize)]
171pub struct RwLockDelta<T: Core>(
172    #[doc(hidden)] pub Option<<T as Core>::Delta>
173);
174
175impl<T: Core> std::fmt::Debug for RwLockDelta<T> {
176    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
177        match &self.0 {
178            Some(d) => write!(f, "RwLockDelta({:#?})", d),
179            None    => write!(f, "RwLockDelta(None)"),
180        }
181    }
182}
183
184
185
186
187#[allow(non_snake_case)]
188#[cfg(test)]
189mod tests {
190    use serde_json;
191    use super::*;
192
193    #[test]
194    fn RwLock__delta__same_values() -> DeltaResult<()> {
195        let s0 = RwLock::new(String::from("foo"));
196        let s1 = RwLock::new(String::from("foo"));
197        let delta: <RwLock<String> as Core>::Delta = s0.delta(&s1)?;
198        let json_string = serde_json::to_string(&delta)
199            .expect("Could not serialize to json");
200        println!("json_string: {}", json_string);
201        assert_eq!(json_string, "\"foo\"");
202        let delta1: <RwLock<String> as Core>::Delta = serde_json::from_str(
203            &json_string
204        ).expect("Could not deserialize from json");
205        assert_eq!(delta, delta1);
206        assert_eq!(delta, RwLock::new(String::from("foo")).into_delta()?);
207        Ok(())
208    }
209
210    #[test]
211    fn RwLock__delta__different_values() -> DeltaResult<()> {
212        let s0 = RwLock::new(String::from("foo"));
213        let s1 = RwLock::new(String::from("bar"));
214        let delta: <RwLock<String> as Core>::Delta = s0.delta(&s1)?;
215        let json_string = serde_json::to_string(&delta)
216            .expect("Could not serialize to json");
217        println!("json_string: {}", json_string);
218        assert_eq!(json_string, "\"bar\"");
219        let delta1: <RwLock<String> as Core>::Delta = serde_json::from_str(
220            &json_string
221        ).expect("Could not deserialize from json");
222        assert_eq!(delta, delta1);
223        assert_eq!(delta, RwLock::new(String::from("bar")).into_delta()?);
224        Ok(())
225    }
226
227    #[test]
228    fn RwLock__apply_same_values() -> DeltaResult<()> {
229        let s0 = RwLock::new(String::from("foo"));
230        let s1 = RwLock::new(String::from("foo"));
231        let delta: <RwLock<String> as Core>::Delta = s0.delta(&s1)?;
232        let s2 = s0.apply(delta)?;
233        assert_eq!(s1, s2);
234        Ok(())
235    }
236
237    #[test]
238    fn RwLock__apply_different_values() -> DeltaResult<()> {
239        let s0 = RwLock::new(String::from("foo"));
240        let s1 = RwLock::new(String::from("bar"));
241        let delta: <RwLock<String> as Core>::Delta = s0.delta(&s1)?;
242        let s2 = s0.apply(delta)?;
243        assert_eq!(s1, s2);
244        Ok(())
245    }
246}