hara_native/lang/data/
sorted_set.rs1use std::cell::Cell;
2
3use crate::lang::data::SortedMap;
4use crate::lang::hash::JavaHash;
5use crate::lang::protocol::{
6 HashType, IColl, IConj, ICount, IDisplay, IDissoc, IEmpty, IEquality, IFind, IHash, IMetadata,
7 IMutable, INth, IObjType, IPersistent, IToMutable, IToPersistent, ObjType,
8};
9
10#[derive(Debug, Clone)]
11pub struct Standard<E> {
12 lookup: SortedMap<E, E>,
13}
14impl<E> Default for Standard<E> {
15 fn default() -> Self {
16 Self {
17 lookup: SortedMap::default(),
18 }
19 }
20}
21impl<E: Clone + Ord> Standard<E> {
22 pub fn new() -> Self {
23 Self::default()
24 }
25 pub fn len(&self) -> usize {
26 self.lookup.len()
27 }
28 pub fn is_empty(&self) -> bool {
29 self.lookup.is_empty()
30 }
31 pub fn get(&self, value: &E) -> Option<&E> {
32 self.lookup.get(value)
33 }
34 pub fn iter(&self) -> impl Iterator<Item = &E> {
35 self.lookup.iter().map(|(key, _)| key)
36 }
37 pub fn conj_value(&self, value: E) -> Self {
38 Self {
39 lookup: self.lookup.assoc_value(value.clone(), value),
40 }
41 }
42 pub fn dissoc_value(&self, value: &E) -> Self {
43 Self {
44 lookup: self.lookup.dissoc_value(value),
45 }
46 }
47 pub fn index_of(&self, value: &E) -> Option<usize> {
48 self.lookup.index_of_key(value)
49 }
50 pub fn inclusive_floor_index(&self, value: &E) -> Option<usize> {
51 self.lookup.inclusive_floor_index(value)
52 }
53 pub fn ceil_index(&self, value: &E) -> Option<usize> {
54 self.lookup.ceil_index(value)
55 }
56 pub fn slice(&self, min: &E, max: &E) -> Self {
57 Self {
58 lookup: self.lookup.slice(min, max),
59 }
60 }
61}
62impl<E: Clone + Ord> FromIterator<E> for Standard<E> {
63 fn from_iter<T: IntoIterator<Item = E>>(it: T) -> Self {
64 it.into_iter().fold(Self::new(), |s, v| s.conj_value(v))
65 }
66}
67impl<E: Clone + Ord> ICount for Standard<E> {
68 fn count(&self) -> usize {
69 self.len()
70 }
71}
72impl<E: Clone + Ord> IFind<E> for Standard<E> {
73 type Output = E;
74 fn find(&self, k: &E) -> Option<E> {
75 self.get(k).cloned()
76 }
77}
78impl<E: Clone + Ord> IConj<E> for Standard<E> {
79 type Output = Self;
80 fn conj(&self, v: E) -> Self {
81 self.conj_value(v)
82 }
83}
84impl<E: Clone + Ord> IDissoc<E> for Standard<E> {
85 type Output = Self;
86 fn dissoc(&self, k: &E) -> Self {
87 self.dissoc_value(k)
88 }
89}
90impl<E: Clone + Ord> INth<E> for Standard<E> {
91 fn nth(&self, i: usize) -> Option<&E> {
92 self.iter().nth(i)
93 }
94}
95impl<E: Clone + Ord> IEmpty for Standard<E> {
96 type Output = Self;
97 fn empty(&self) -> Self {
98 Self {
99 lookup: self.lookup.empty(),
100 }
101 }
102}
103impl<E: Clone + Ord> IMetadata for Standard<E> {
104 type Metadata = std::rc::Rc<crate::lang::data::Metadata>;
105 fn meta(&self) -> Option<&Self::Metadata> {
106 self.lookup.meta()
107 }
108 fn with_meta(&self, metadata: Option<Self::Metadata>) -> Self {
109 Self {
110 lookup: self.lookup.with_meta(metadata),
111 }
112 }
113}
114impl<E: Clone + Ord> IPersistent for Standard<E> {}
115impl<E: Clone + Ord> IntoIterator for Standard<E> {
116 type Item = E;
117 type IntoIter = std::vec::IntoIter<E>;
118 fn into_iter(self) -> Self::IntoIter {
119 self.iter().cloned().collect::<Vec<_>>().into_iter()
120 }
121}
122impl<E: Clone + Ord> IEquality for Standard<E> {
123 fn equality(&self, other: &Self) -> bool {
124 self.len() == other.len() && self.iter().eq(other.iter())
125 }
126}
127impl<E: Clone + Ord + std::fmt::Debug> IDisplay for Standard<E> {
128 fn display(&self) -> String {
129 format!(
130 "#{{{}}}",
131 self.iter()
132 .map(|v| format!("{v:?}"))
133 .collect::<Vec<_>>()
134 .join(" ")
135 )
136 }
137}
138impl<E: Clone + Ord + std::hash::Hash + JavaHash> IHash for Standard<E> {
139 fn hash_calc(&self, hash_type: HashType) -> u64 {
140 crate::lang::hash::compose_unordered("SET", self.iter().map(|v| v.java_hash(hash_type)))
143 as u64
144 }
145}
146impl<E: Clone + Ord + std::fmt::Debug> IObjType for Standard<E> {
147 fn obj_type(&self) -> ObjType {
148 ObjType::Set
149 }
150}
151impl<E> IColl<E> for Standard<E>
152where
153 E: Clone + Ord + std::hash::Hash + JavaHash + std::fmt::Debug,
154{
155 fn start_string(&self) -> &'static str {
156 "#{"
157 }
158 fn end_string(&self) -> &'static str {
159 "}"
160 }
161}
162impl<E: Clone + Ord> IToMutable for Standard<E> {
163 type Mutable = Mutable<E>;
164 fn to_mutable(&self) -> Self::Mutable {
165 Mutable {
166 editable: Cell::new(true),
167 set: self.clone(),
168 }
169 }
170}
171
172#[derive(Debug, Clone)]
173pub struct Mutable<E> {
174 editable: Cell<bool>,
175 set: Standard<E>,
176}
177impl<E: Clone + Ord> Mutable<E> {
178 fn check(&self) {
179 assert!(
180 self.editable.get(),
181 "mutable sorted set used after to_persistent"
182 )
183 }
184 pub fn conj(&mut self, v: E) -> &mut Self {
185 self.check();
186 self.set = self.set.conj_value(v);
187 self
188 }
189 pub fn dissoc(&mut self, v: &E) -> &mut Self {
190 self.check();
191 self.set = self.set.dissoc_value(v);
192 self
193 }
194}
195impl<E: Clone + Ord> std::ops::Deref for Mutable<E> {
196 type Target = Standard<E>;
197 fn deref(&self) -> &Self::Target {
198 self.check();
199 &self.set
200 }
201}
202impl<E> IMutable for Mutable<E> {}
203impl<E: Clone + Ord> IToPersistent for Mutable<E> {
204 type Persistent = Standard<E>;
205 fn to_persistent(&mut self) -> Self::Persistent {
206 self.check();
207 self.editable.set(false);
208 self.set.clone()
209 }
210}
211
212#[cfg(test)]
213mod tests {
214 use super::Standard;
215 #[test]
216 fn updates_slices_empty_and_mutable_preserve_metadata() {
217 use crate::lang::protocol::{IEmpty, IMetadata, IToMutable, IToPersistent};
218 let set = [1, 2, 3]
219 .into_iter()
220 .collect::<Standard<_>>()
221 .with_meta(Some(crate::lang::data::Metadata::document("doc")));
222 for value in [
223 set.conj_value(4),
224 set.dissoc_value(&1),
225 set.slice(&1, &2),
226 set.empty(),
227 ] {
228 assert_eq!(value.meta().map(|m| m.doc().unwrap()), Some("doc"));
229 }
230 let mut mutable = set.to_mutable();
231 mutable.conj(4);
232 assert_eq!(
233 mutable.to_persistent().meta().map(|m| m.doc().unwrap()),
234 Some("doc")
235 );
236 }
237
238 #[test]
239 fn deduplicates_and_sorts() {
240 let set = [4, 1, 3, 1, 2].into_iter().collect::<Standard<_>>();
241 assert_eq!(set.iter().copied().collect::<Vec<_>>(), vec![1, 2, 3, 4]);
242 assert_eq!(set.index_of(&3), Some(2));
243 assert_eq!(
244 set.slice(&2, &3).iter().copied().collect::<Vec<_>>(),
245 vec![2, 3]
246 );
247 }
248}