sim_table_override/
override_table.rs1use std::collections::BTreeSet;
6
7use sim_kernel::{
8 Cx, Error, Expr, Object, ObjectEncode, ObjectEncoding, Result, Symbol, Table, Value,
9 id::CORE_TABLE_CLASS_ID, object::ClassRef,
10};
11
12#[derive(Clone)]
22pub struct OverrideTable {
23 layers: Vec<Value>,
24}
25
26impl OverrideTable {
27 pub fn new(layers: Vec<Value>) -> Result<Self> {
35 if layers.is_empty() {
36 return Err(Error::Eval(
37 "table/override: expected at least one table layer".to_owned(),
38 ));
39 }
40 for layer in &layers {
41 if layer.object().as_table_impl().is_none() {
42 return Err(Error::Eval(
43 "table/override: every layer must be a table".to_owned(),
44 ));
45 }
46 }
47 Ok(Self { layers })
48 }
49
50 pub fn layers(&self) -> &[Value] {
52 &self.layers
53 }
54
55 fn front(&self) -> &Value {
56 &self.layers[0]
57 }
58}
59
60impl Object for OverrideTable {
61 fn display(&self, _cx: &mut Cx) -> Result<String> {
62 Ok(format!("table/override[layers={}]", self.layers.len()))
63 }
64
65 fn as_any(&self) -> &dyn std::any::Any {
66 self
67 }
68}
69
70impl sim_kernel::ObjectCompat for OverrideTable {
71 fn class(&self, cx: &mut Cx) -> Result<ClassRef> {
72 let symbol = Symbol::qualified("core", "Table");
73 if let Some(value) = cx.registry().class_by_symbol(&symbol) {
74 return Ok(value.clone());
75 }
76 cx.factory().class_stub(CORE_TABLE_CLASS_ID, symbol)
77 }
78 fn as_expr(&self, cx: &mut Cx) -> Result<Expr> {
79 self.as_table_expr(cx)
80 }
81 fn truth(&self, cx: &mut Cx) -> Result<bool> {
82 Ok(!self.is_empty(cx)?)
83 }
84 fn as_table_impl(&self) -> Option<&dyn Table> {
85 Some(self)
86 }
87 fn as_object_encoder(&self) -> Option<&dyn ObjectEncode> {
88 Some(self)
89 }
90}
91
92impl ObjectEncode for OverrideTable {
93 fn object_encoding(&self, cx: &mut Cx) -> Result<ObjectEncoding> {
94 let args = self
95 .layers
96 .iter()
97 .map(|layer| layer.object().as_expr(cx))
98 .collect::<Result<Vec<_>>>()?;
99 Ok(ObjectEncoding::Constructor {
100 class: Symbol::new("OverrideTable"),
101 args,
102 })
103 }
104}
105
106impl sim_citizen::Citizen for OverrideTable {
107 fn citizen_symbol() -> Symbol {
108 Symbol::new("OverrideTable")
109 }
110
111 fn citizen_version() -> u32 {
112 0
113 }
114
115 fn citizen_arity() -> usize {
116 1
117 }
118
119 fn citizen_fields() -> &'static [&'static str] {
120 &["layer"]
121 }
122}
123
124impl Table for OverrideTable {
125 fn backend_symbol(&self) -> Symbol {
126 Symbol::qualified("table", "override")
127 }
128
129 fn get(&self, cx: &mut Cx, key: Symbol) -> Result<Value> {
130 for layer in &self.layers {
131 let table = layer
132 .object()
133 .as_table_impl()
134 .expect("validated table layer");
135 if table.has(cx, key.clone())? {
136 return table.get(cx, key);
137 }
138 }
139 cx.factory().nil()
140 }
141
142 fn set(&self, cx: &mut Cx, key: Symbol, value: Value) -> Result<()> {
143 self.front()
144 .object()
145 .as_table_impl()
146 .expect("validated table layer")
147 .set(cx, key, value)
148 }
149
150 fn has(&self, cx: &mut Cx, key: Symbol) -> Result<bool> {
151 for layer in &self.layers {
152 if layer
153 .object()
154 .as_table_impl()
155 .expect("validated table layer")
156 .has(cx, key.clone())?
157 {
158 return Ok(true);
159 }
160 }
161 Ok(false)
162 }
163
164 fn del(&self, cx: &mut Cx, key: Symbol) -> Result<Value> {
165 self.front()
166 .object()
167 .as_table_impl()
168 .expect("validated table layer")
169 .del(cx, key)
170 }
171
172 fn keys(&self, cx: &mut Cx) -> Result<Vec<Symbol>> {
173 let mut seen = BTreeSet::new();
174 let mut out = Vec::new();
175 for layer in &self.layers {
176 for key in layer
177 .object()
178 .as_table_impl()
179 .expect("validated table layer")
180 .keys(cx)?
181 {
182 if seen.insert(key.clone()) {
183 out.push(key);
184 }
185 }
186 }
187 Ok(out)
188 }
189
190 fn entries(&self, cx: &mut Cx) -> Result<Vec<(Symbol, Value)>> {
191 let mut seen = BTreeSet::new();
192 let mut out = Vec::new();
193 for layer in &self.layers {
194 for (key, value) in layer
195 .object()
196 .as_table_impl()
197 .expect("validated table layer")
198 .entries(cx)?
199 {
200 if seen.insert(key.clone()) {
201 out.push((key, value));
202 }
203 }
204 }
205 Ok(out)
206 }
207
208 fn len(&self, cx: &mut Cx) -> Result<usize> {
209 Ok(self.keys(cx)?.len())
210 }
211
212 fn clear(&self, cx: &mut Cx) -> Result<()> {
213 self.front()
214 .object()
215 .as_table_impl()
216 .expect("validated table layer")
217 .clear(cx)
218 }
219}