sim_lib_sequence/
persistent.rs1use std::sync::Arc;
2
3use sim_kernel::{Cx, Error, Expr, Object, ObjectCompat, Result, Symbol, Value, force_list_to_vec};
4
5#[sim_citizen_derive::non_citizen(
6 reason = "persistent vector wrapper; canonical form is native Expr::Vector data",
7 kind = "marker",
8 descriptor = "core/Expr"
9)]
10#[derive(Clone, Debug)]
16pub struct PersistentVector {
17 items: Arc<[Value]>,
18}
19
20impl PersistentVector {
21 pub fn new(items: Vec<Value>) -> Self {
23 Self {
24 items: Arc::from(items),
25 }
26 }
27
28 pub fn items(&self) -> &[Value] {
30 &self.items
31 }
32}
33
34impl Object for PersistentVector {
35 fn display(&self, _cx: &mut Cx) -> Result<String> {
36 Ok(format!("#<sequence-vector {}>", self.items.len()))
37 }
38
39 fn as_any(&self) -> &dyn std::any::Any {
40 self
41 }
42}
43
44impl ObjectCompat for PersistentVector {
45 fn as_expr(&self, cx: &mut Cx) -> Result<Expr> {
46 Ok(Expr::Vector(
47 self.items
48 .iter()
49 .map(|value| value.object().as_expr(cx))
50 .collect::<Result<Vec<_>>>()?,
51 ))
52 }
53
54 fn truth(&self, _cx: &mut Cx) -> Result<bool> {
55 Ok(!self.items.is_empty())
56 }
57}
58
59#[sim_citizen_derive::non_citizen(
60 reason = "persistent set wrapper; canonical form is native Expr::Set data",
61 kind = "marker",
62 descriptor = "core/Expr"
63)]
64#[derive(Clone, Debug)]
70pub struct PersistentSet {
71 items: Arc<[Value]>,
72}
73
74impl PersistentSet {
75 pub fn new(cx: &mut Cx, items: Vec<Value>) -> Result<Self> {
77 let mut unique = Vec::new();
78 for item in items {
79 if !contains_canonical(cx, &unique, &item)? {
80 unique.push(item);
81 }
82 }
83 Ok(Self {
84 items: Arc::from(unique),
85 })
86 }
87
88 pub fn items(&self) -> &[Value] {
90 &self.items
91 }
92}
93
94impl Object for PersistentSet {
95 fn display(&self, _cx: &mut Cx) -> Result<String> {
96 Ok(format!("#<sequence-set {}>", self.items.len()))
97 }
98
99 fn as_any(&self) -> &dyn std::any::Any {
100 self
101 }
102}
103
104impl ObjectCompat for PersistentSet {
105 fn as_expr(&self, cx: &mut Cx) -> Result<Expr> {
106 Ok(Expr::Set(
107 self.items
108 .iter()
109 .map(|value| value.object().as_expr(cx))
110 .collect::<Result<Vec<_>>>()?,
111 ))
112 }
113
114 fn truth(&self, _cx: &mut Cx) -> Result<bool> {
115 Ok(!self.items.is_empty())
116 }
117}
118
119pub fn persistent_list(cx: &mut Cx, items: Vec<Value>) -> Result<Value> {
121 cx.new_list(items)
122}
123
124pub fn persistent_list_push(cx: &mut Cx, list: &Value, item: Value) -> Result<Value> {
126 let mut items = list_items(cx, list)?;
127 items.push(item);
128 cx.new_list(items)
129}
130
131pub fn persistent_vector(cx: &mut Cx, items: Vec<Value>) -> Result<Value> {
150 cx.factory().opaque(Arc::new(PersistentVector::new(items)))
151}
152
153pub fn persistent_vector_push(cx: &mut Cx, vector: &Value, item: Value) -> Result<Value> {
155 let vector = vector_value(vector)?;
156 let mut items = vector.items().to_vec();
157 items.push(item);
158 persistent_vector(cx, items)
159}
160
161pub fn persistent_set(cx: &mut Cx, items: Vec<Value>) -> Result<Value> {
163 let set = PersistentSet::new(cx, items)?;
164 cx.factory().opaque(Arc::new(set))
165}
166
167pub fn persistent_set_insert(cx: &mut Cx, set: &Value, item: Value) -> Result<Value> {
169 let set = set_value(set)?;
170 let mut items = set.items().to_vec();
171 if !contains_canonical(cx, &items, &item)? {
172 items.push(item);
173 }
174 persistent_set(cx, items)
175}
176
177pub fn persistent_map(cx: &mut Cx, entries: Vec<(Symbol, Value)>) -> Result<Value> {
179 cx.new_table(entries)
180}
181
182pub fn persistent_map_assoc(cx: &mut Cx, map: &Value, key: Symbol, value: Value) -> Result<Value> {
186 let table = map.object().as_table_impl().ok_or(Error::TypeMismatch {
187 expected: "table",
188 found: "non-table",
189 })?;
190 let mut entries = table.entries(cx)?;
191 match entries.iter_mut().find(|(candidate, _)| *candidate == key) {
192 Some((_, slot)) => *slot = value,
193 None => entries.push((key, value)),
194 }
195 cx.new_table(entries)
196}
197
198fn list_items(cx: &mut Cx, value: &Value) -> Result<Vec<Value>> {
199 let list = value.object().as_list().ok_or(Error::TypeMismatch {
200 expected: "list",
201 found: "non-list",
202 })?;
203 force_list_to_vec(cx, list, "sequence persistent list")
204}
205
206fn vector_value(value: &Value) -> Result<&PersistentVector> {
207 value
208 .object()
209 .downcast_ref::<PersistentVector>()
210 .ok_or(Error::TypeMismatch {
211 expected: "sequence vector",
212 found: "non-vector",
213 })
214}
215
216fn set_value(value: &Value) -> Result<&PersistentSet> {
217 value
218 .object()
219 .downcast_ref::<PersistentSet>()
220 .ok_or(Error::TypeMismatch {
221 expected: "sequence set",
222 found: "non-set",
223 })
224}
225
226fn contains_canonical(cx: &mut Cx, values: &[Value], candidate: &Value) -> Result<bool> {
227 let candidate = candidate.object().as_expr(cx)?;
228 for value in values {
229 if value.object().as_expr(cx)?.canonical_eq(&candidate) {
230 return Ok(true);
231 }
232 }
233 Ok(false)
234}