hara_native/lang/data/
adapters.rs1use std::collections::{HashMap, HashSet, VecDeque};
2use std::hash::Hash;
3
4#[derive(Debug, Clone, Default)]
5pub struct AsList<E>(VecDeque<E>);
6impl<E> AsList<E> {
7 pub fn new(values: impl IntoIterator<Item = E>) -> Self {
8 Self(values.into_iter().collect())
9 }
10 pub fn len(&self) -> usize {
11 self.0.len()
12 }
13 pub fn is_empty(&self) -> bool {
14 self.0.is_empty()
15 }
16 pub fn empty(&mut self) -> &mut Self {
17 self.0.clear();
18 self
19 }
20 pub fn nth(&self, index: usize) -> Option<&E> {
21 self.0.get(index)
22 }
23 pub fn peek_first(&self) -> Option<&E> {
24 self.0.front()
25 }
26 pub fn peek_last(&self) -> Option<&E> {
27 self.0.back()
28 }
29 pub fn pop_first(&mut self) -> Option<E> {
30 self.0.pop_front()
31 }
32 pub fn pop_last(&mut self) -> Option<E> {
33 self.0.pop_back()
34 }
35 pub fn push_first(&mut self, value: E) -> &mut Self {
36 self.0.push_front(value);
37 self
38 }
39 pub fn push_last(&mut self, value: E) -> &mut Self {
40 self.0.push_back(value);
41 self
42 }
43 pub fn iter(&self) -> impl Iterator<Item = &E> {
44 self.0.iter()
45 }
46}
47
48#[derive(Debug, Clone, Default)]
49pub struct AsMap<K, V>(HashMap<K, V>);
50impl<K: Eq + Hash, V> AsMap<K, V> {
51 pub fn new(values: impl IntoIterator<Item = (K, V)>) -> Self {
52 Self(values.into_iter().collect())
53 }
54 pub fn len(&self) -> usize {
55 self.0.len()
56 }
57 pub fn is_empty(&self) -> bool {
58 self.0.is_empty()
59 }
60 pub fn assoc(&mut self, key: K, value: V) -> &mut Self {
61 self.0.insert(key, value);
62 self
63 }
64 pub fn dissoc(&mut self, key: &K) -> &mut Self {
65 self.0.remove(key);
66 self
67 }
68 pub fn empty(&mut self) -> &mut Self {
69 self.0.clear();
70 self
71 }
72 pub fn find(&self, key: &K) -> Option<(&K, &V)> {
73 self.0.get_key_value(key)
74 }
75 pub fn get(&self, key: &K) -> Option<&V> {
76 self.0.get(key)
77 }
78 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
79 self.0.iter()
80 }
81}
82
83#[derive(Debug, Clone, Default)]
84pub struct AsSet<E>(HashSet<E>);
85impl<E: Eq + Hash> AsSet<E> {
86 pub fn new(values: impl IntoIterator<Item = E>) -> Self {
87 Self(values.into_iter().collect())
88 }
89 pub fn len(&self) -> usize {
90 self.0.len()
91 }
92 pub fn is_empty(&self) -> bool {
93 self.0.is_empty()
94 }
95 pub fn conj(&mut self, value: E) -> &mut Self {
96 self.0.insert(value);
97 self
98 }
99 pub fn dissoc(&mut self, value: &E) -> &mut Self {
100 self.0.remove(value);
101 self
102 }
103 pub fn empty(&mut self) -> &mut Self {
104 self.0.clear();
105 self
106 }
107 pub fn find(&self, value: &E) -> Option<&E> {
108 self.0.get(value)
109 }
110 pub fn iter(&self) -> impl Iterator<Item = &E> {
111 self.0.iter()
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::{AsList, AsMap, AsSet};
118 #[test]
119 fn expose_mutable_host_collections() {
120 let mut list = AsList::new([2]);
121 list.push_first(1).push_last(3);
122 assert_eq!(list.iter().copied().collect::<Vec<_>>(), vec![1, 2, 3]);
123 let mut map = AsMap::new([]);
124 map.assoc("a", 1);
125 assert_eq!(map.get(&"a"), Some(&1));
126 let mut set = AsSet::new([1, 1]);
127 set.conj(2);
128 assert_eq!(set.len(), 2);
129 }
130}