tirea_state/lattice/
max_reg.rs1use serde::{Deserialize, Serialize};
2
3use super::Lattice;
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(transparent)]
10pub struct MaxReg<T: Ord>(T);
11
12impl<T: Ord> MaxReg<T> {
13 pub fn new(value: T) -> Self {
15 Self(value)
16 }
17
18 pub fn value(&self) -> &T {
20 &self.0
21 }
22
23 pub fn set(&mut self, value: T) {
25 self.0 = value;
26 }
27}
28
29impl<T: Ord + Clone + PartialEq> Lattice for MaxReg<T> {
30 fn merge(&self, other: &Self) -> Self {
31 if self.0 >= other.0 {
32 self.clone()
33 } else {
34 other.clone()
35 }
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use crate::lattice::assert_lattice_laws;
43
44 #[test]
45 fn new_and_value() {
46 let r = MaxReg::new(42);
47 assert_eq!(*r.value(), 42);
48 }
49
50 #[test]
51 fn set_replaces() {
52 let mut r = MaxReg::new(1);
53 r.set(100);
54 assert_eq!(*r.value(), 100);
55 }
56
57 #[test]
58 fn lattice_laws_i64() {
59 let a = MaxReg::new(1i64);
60 let b = MaxReg::new(5);
61 let c = MaxReg::new(3);
62 assert_lattice_laws(&a, &b, &c);
63
64 let a = MaxReg::new(10i64);
65 let b = MaxReg::new(10);
66 let c = MaxReg::new(7);
67 assert_lattice_laws(&a, &b, &c);
68 }
69
70 #[test]
71 fn lattice_laws_string() {
72 let a = MaxReg::new("alpha".to_string());
73 let b = MaxReg::new("gamma".to_string());
74 let c = MaxReg::new("beta".to_string());
75 assert_lattice_laws(&a, &b, &c);
76 }
77
78 #[test]
79 fn merge_takes_max() {
80 let a = MaxReg::new(3);
81 let b = MaxReg::new(7);
82 assert_eq!(*a.merge(&b).value(), 7);
83 assert_eq!(*b.merge(&a).value(), 7);
84 }
85
86 #[test]
87 fn merge_equal_values() {
88 let a = MaxReg::new(5);
89 let b = MaxReg::new(5);
90 assert_eq!(*a.merge(&b).value(), 5);
91 }
92
93 #[test]
94 fn serde_roundtrip() {
95 let r = MaxReg::new(42i64);
96 let json = serde_json::to_value(&r).unwrap();
97 assert_eq!(json, serde_json::json!(42));
98
99 let back: MaxReg<i64> = serde_json::from_value(json).unwrap();
100 assert_eq!(back, r);
101 }
102
103 #[test]
104 fn serde_string_roundtrip() {
105 let r = MaxReg::new("hello".to_string());
106 let json = serde_json::to_value(&r).unwrap();
107 assert_eq!(json, serde_json::json!("hello"));
108
109 let back: MaxReg<String> = serde_json::from_value(json).unwrap();
110 assert_eq!(back, r);
111 }
112}