cljrs_value/collections/
sorted_map.rs1use crate::Value;
2
3#[derive(Debug, Clone)]
5pub struct SortedMap {
6 inner: rpds::RedBlackTreeMapSync<Value, Value>,
7}
8
9impl SortedMap {
10 pub fn empty() -> Self {
11 Self {
12 inner: rpds::RedBlackTreeMapSync::new_sync(),
13 }
14 }
15
16 pub fn count(&self) -> usize {
17 self.inner.size()
18 }
19
20 pub fn is_empty(&self) -> bool {
21 self.inner.is_empty()
22 }
23
24 pub fn get(&self, key: &Value) -> Option<&Value> {
25 self.inner.get(key)
26 }
27
28 pub fn contains_key(&self, key: &Value) -> bool {
29 self.inner.contains_key(key)
30 }
31
32 pub fn assoc(&self, key: Value, value: Value) -> Self {
33 Self {
34 inner: self.inner.insert(key, value),
35 }
36 }
37
38 pub fn dissoc(&self, key: &Value) -> Self {
39 Self {
40 inner: self.inner.remove(key),
41 }
42 }
43
44 pub fn iter(&self) -> impl Iterator<Item = (&Value, &Value)> {
46 self.inner.iter()
47 }
48
49 pub fn keys(&self) -> Vec<Value> {
50 self.inner.keys().cloned().collect()
51 }
52
53 pub fn vals(&self) -> Vec<Value> {
54 self.inner.values().cloned().collect()
55 }
56
57 pub fn from_pairs<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self {
58 let mut m = Self::empty();
59 for (k, v) in iter {
60 m = m.assoc(k, v);
61 }
62 m
63 }
64}
65
66impl PartialEq for SortedMap {
67 fn eq(&self, other: &Self) -> bool {
68 if self.count() != other.count() {
69 return false;
70 }
71 self.inner.iter().all(|(k, v)| other.get(k) == Some(v))
72 }
73}
74
75impl cljrs_gc::Trace for SortedMap {
76 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
77 for (k, v) in self.inner.iter() {
78 k.trace(visitor);
79 v.trace(visitor);
80 }
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::Value;
88
89 fn int(n: i64) -> Value {
90 Value::Long(n)
91 }
92
93 #[test]
94 fn test_basic_ops() {
95 let m = SortedMap::empty();
96 let m = m.assoc(int(3), int(30));
97 let m = m.assoc(int(1), int(10));
98 let m = m.assoc(int(2), int(20));
99 assert_eq!(m.count(), 3);
100 assert_eq!(m.get(&int(1)), Some(&int(10)));
101 assert_eq!(m.get(&int(2)), Some(&int(20)));
102 assert_eq!(m.get(&int(3)), Some(&int(30)));
103 }
104
105 #[test]
106 fn test_sorted_iteration_order() {
107 let m = SortedMap::empty()
108 .assoc(int(3), int(30))
109 .assoc(int(1), int(10))
110 .assoc(int(2), int(20));
111 let keys: Vec<Value> = m.iter().map(|(k, _)| k.clone()).collect();
112 assert_eq!(keys, vec![int(1), int(2), int(3)]);
113 }
114
115 #[test]
116 fn test_dissoc() {
117 let m = SortedMap::empty()
118 .assoc(int(1), int(10))
119 .assoc(int(2), int(20));
120 let m2 = m.dissoc(&int(1));
121 assert_eq!(m2.count(), 1);
122 assert_eq!(m2.get(&int(1)), None);
123 assert_eq!(m2.get(&int(2)), Some(&int(20)));
124 }
125}