Skip to main content

rustrade_integration/collection/
snapshot.rs

1use derive_more::{Constructor, From};
2use serde::{Deserialize, Serialize};
3
4#[derive(
5    Debug,
6    Clone,
7    Copy,
8    Eq,
9    PartialEq,
10    Ord,
11    PartialOrd,
12    Hash,
13    Deserialize,
14    Serialize,
15    Constructor,
16    From,
17)]
18pub struct Snapshot<T>(pub T);
19
20impl<T> Snapshot<T> {
21    pub fn value(&self) -> &T {
22        &self.0
23    }
24
25    pub fn as_ref(&self) -> Snapshot<&T> {
26        let Self(item) = self;
27        Snapshot(item)
28    }
29
30    pub fn map<F, N>(self, op: F) -> Snapshot<N>
31    where
32        F: Fn(T) -> N,
33    {
34        let Self(item) = self;
35        Snapshot(op(item))
36    }
37}
38
39#[derive(
40    Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
41)]
42pub struct SnapUpdates<Snapshot, Updates> {
43    pub snapshot: Snapshot,
44    pub updates: Updates,
45}
46
47#[cfg(test)]
48#[allow(clippy::unwrap_used)] // Test code: panics on bad input are acceptable
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_snapshot_value() {
54        let snap = Snapshot::new(42);
55        assert_eq!(snap.value(), &42);
56    }
57
58    #[test]
59    fn test_snapshot_as_ref() {
60        let snap = Snapshot::new(String::from("hello"));
61        let snap_ref = snap.as_ref();
62        assert_eq!(*snap_ref.value(), "hello");
63    }
64
65    #[test]
66    fn test_snapshot_map() {
67        let snap = Snapshot::new(10);
68        let doubled = snap.map(|x| x * 2);
69        assert_eq!(doubled.value(), &20);
70    }
71
72    #[test]
73    fn test_snapshot_serde_round_trip() {
74        let snap = Snapshot::new(42u64);
75        let json = serde_json::to_string(&snap).unwrap();
76        let deserialised: Snapshot<u64> = serde_json::from_str(&json).unwrap();
77        assert_eq!(deserialised, snap);
78    }
79
80    #[test]
81    fn test_snap_updates_construction() {
82        let snap_updates = SnapUpdates::new(Snapshot::new(1), vec![2, 3, 4]);
83        assert_eq!(snap_updates.snapshot, Snapshot::new(1));
84        assert_eq!(snap_updates.updates, vec![2, 3, 4]);
85    }
86
87    #[test]
88    fn test_snap_updates_serde_round_trip() {
89        let snap_updates = SnapUpdates::new(Snapshot::new("state"), vec!["a", "b"]);
90        let json = serde_json::to_string(&snap_updates).unwrap();
91        let deserialised: SnapUpdates<Snapshot<&str>, Vec<&str>> =
92            serde_json::from_str(&json).unwrap();
93        assert_eq!(deserialised, snap_updates);
94    }
95}