1use crate::matrix::Matrix;
2use crate::*;
3use crate::nodes::Matrix as Mat;
4use crate::{MechError, MechErrorKind, hash_str, nodes::Kind as NodeKind, nodes::*, humanize};
5use std::collections::HashMap;
6
7use na::{Vector3, DVector, Vector2, Vector4, RowDVector, Matrix1, Matrix3, Matrix4, RowVector3, RowVector4, RowVector2, DMatrix, Rotation3, Matrix2x3, Matrix3x2, Matrix6, Matrix2};
8use std::hash::{Hash, Hasher};
9use indexmap::set::IndexSet;
10use indexmap::map::*;
11use tabled::{
12 builder::Builder,
13 settings::{object::Rows,Panel, Span, Alignment, Modify, Style},
14 Tabled,
15};
16use paste::paste;
17use serde::ser::{Serialize, Serializer, SerializeStruct};
18use serde::de::{self, Deserialize, SeqAccess, Deserializer, MapAccess, Visitor};
19use std::fmt;
20use std::cell::RefCell;
21use std::rc::Rc;
22
23macro_rules! impl_as_type {
24 ($target_type:ty) => {
25 paste!{
26 pub fn [<as_ $target_type>](&self) -> Option<Ref<$target_type>> {
27 match self {
28 Value::U8(v) => Some(new_ref(*v.borrow() as $target_type)),
29 Value::U16(v) => Some(new_ref(*v.borrow() as $target_type)),
30 Value::U32(v) => Some(new_ref(*v.borrow() as $target_type)),
31 Value::U64(v) => Some(new_ref(*v.borrow() as $target_type)),
32 Value::U128(v) => Some(new_ref(*v.borrow() as $target_type)),
33 Value::I8(v) => Some(new_ref(*v.borrow() as $target_type)),
34 Value::I16(v) => Some(new_ref(*v.borrow() as $target_type)),
35 Value::I32(v) => Some(new_ref(*v.borrow() as $target_type)),
36 Value::I64(v) => Some(new_ref(*v.borrow() as $target_type)),
37 Value::I128(v) => Some(new_ref(*v.borrow() as $target_type)),
38 Value::F32(v) => Some(new_ref((*v.borrow()).0 as $target_type)),
39 Value::F64(v) => Some(new_ref((*v.borrow()).0 as $target_type)),
40 Value::MutableReference(val) => val.borrow().[<as_ $target_type>](),
41 _ => None,
42 }
43 }
44 }
45 };
46}
47
48#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
51pub enum ValueKind {
52 U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64,
53 String, Bool, Matrix(Box<ValueKind>,Vec<usize>), Enum(u64), Set(Box<ValueKind>, usize),
54 Map(Box<ValueKind>,Box<ValueKind>), Record(Vec<ValueKind>), Table(Vec<ValueKind>, usize), Tuple(Vec<ValueKind>), Id, Index, Reference(Box<ValueKind>), Atom(u64), Empty, Any
55}
56
57impl ValueKind {
58
59 pub fn deref_kind(&self) -> Option<ValueKind> {
60 match self {
61 ValueKind::Reference(x) => Some(*x.clone()),
62 _ => None,
63 }
64 }
65
66}
67
68impl std::fmt::Display for ValueKind {
69 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
70 match self {
71 ValueKind::U8 => write!(f, "u8"),
72 ValueKind::U16 => write!(f, "u16"),
73 ValueKind::U32 => write!(f, "u32"),
74 ValueKind::U64 => write!(f, "u64"),
75 ValueKind::U128 => write!(f, "u128"),
76 ValueKind::I8 => write!(f, "i8"),
77 ValueKind::I16 => write!(f, "i16"),
78 ValueKind::I32 => write!(f, "i32"),
79 ValueKind::I64 => write!(f, "i64"),
80 ValueKind::I128 => write!(f, "i128"),
81 ValueKind::F32 => write!(f, "f32"),
82 ValueKind::F64 => write!(f, "f64"),
83 ValueKind::String => write!(f, "string"),
84 ValueKind::Bool => write!(f, "bool"),
85 ValueKind::Matrix(x,s) => write!(f, "[{:?}]:{:?},{:?}",x,s[0],s[1]),
86 ValueKind::Enum(x) => write!(f, "{:?}",x),
87 ValueKind::Set(x,el) => write!(f, "{{{:?}}}:{}", x, el),
88 ValueKind::Map(x,y) => write!(f, "{{{:?}:{:?}}}",x,y),
89 ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
90 ValueKind::Table(x,y) => write!(f, "{{{}}}:{}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(","),y),
91 ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
92 ValueKind::Id => write!(f, "id"),
93 ValueKind::Index => write!(f, "ix"),
94 ValueKind::Reference(x) => write!(f, "{:?}",x),
95 ValueKind::Atom(x) => write!(f, "`{:?}",x),
96 ValueKind::Empty => write!(f, "_"),
97 ValueKind::Any => write!(f, "_"),
98 }
99 }
100}
101
102
103impl fmt::Debug for ValueKind {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 match self {
106 ValueKind::U8 => write!(f, "u8"),
107 ValueKind::U16 => write!(f, "u16"),
108 ValueKind::U32 => write!(f, "u32"),
109 ValueKind::U64 => write!(f, "u64"),
110 ValueKind::U128 => write!(f, "u128"),
111 ValueKind::I8 => write!(f, "i8"),
112 ValueKind::I16 => write!(f, "i16"),
113 ValueKind::I32 => write!(f, "i32"),
114 ValueKind::I64 => write!(f, "i64"),
115 ValueKind::I128 => write!(f, "i128"),
116 ValueKind::F32 => write!(f, "f32"),
117 ValueKind::F64 => write!(f, "f64"),
118 ValueKind::String => write!(f, "string"),
119 ValueKind::Bool => write!(f, "bool"),
120 ValueKind::Matrix(x,s) => {
121 let s = if s.len() == 2 { s.clone() } else if s.len() == 1 { vec![s[0], 1] } else { vec![0, 0] };
122 write!(f, "[{:?}]:{:?},{:?}",x,s[0],s[1]).clone()
123 }
124 ValueKind::Enum(x) => write!(f, "{:?}",x),
125 ValueKind::Set(x,el) => write!(f, "{{{:?}}}:{}", x, el),
126 ValueKind::Map(x,y) => write!(f, "{{{:?}:{:?}}}",x,y),
127 ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
128 ValueKind::Table(x,y) => write!(f, "{{{}}}:{}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(","),y),
129 ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
130 ValueKind::Id => write!(f, "id"),
131 ValueKind::Index => write!(f, "ix"),
132 ValueKind::Reference(x) => write!(f, "&{:?}",x),
133 ValueKind::Atom(x) => write!(f, "`{:?}",x),
134 ValueKind::Empty => write!(f, "_"),
135 ValueKind::Any => write!(f, "_"),
136 }
137 }
138}
139
140impl ValueKind {
141 pub fn is_compatible(k1: ValueKind, k2: ValueKind) -> bool {
142 match k1 {
143 ValueKind::Reference(x) => {
144 ValueKind::is_compatible(*x,k2)
145 }
146 ValueKind::Matrix(x,_) => {
147 *x == k2
148 }
149 x => x == k2,
150 }
151 }
152}
153
154#[derive(Clone, Debug, PartialEq, Eq)]
155pub enum Value {
156 U8(Ref<u8>),
157 U16(Ref<u16>),
158 U32(Ref<u32>),
159 U64(Ref<u64>),
160 U128(Ref<u128>),
161 I8(Ref<i8>),
162 I16(Ref<i16>),
163 I32(Ref<i32>),
164 I64(Ref<i64>),
165 I128(Ref<i128>),
166 F32(Ref<F32>),
167 F64(Ref<F64>),
168 String(Ref<String>),
169 Bool(Ref<bool>),
170 Atom(u64),
171 MatrixIndex(Matrix<usize>),
172 MatrixBool(Matrix<bool>),
173 MatrixU8(Matrix<u8>),
174 MatrixU16(Matrix<u16>),
175 MatrixU32(Matrix<u32>),
176 MatrixU64(Matrix<u64>),
177 MatrixU128(Matrix<u128>),
178 MatrixI8(Matrix<i8>),
179 MatrixI16(Matrix<i16>),
180 MatrixI32(Matrix<i32>),
181 MatrixI64(Matrix<i64>),
182 MatrixI128(Matrix<i128>),
183 MatrixF32(Matrix<F32>),
184 MatrixF64(Matrix<F64>),
185 MatrixString(Matrix<String>),
186 MatrixValue(Matrix<Value>),
187 Set(MechSet),
188 Map(MechMap),
189 Record(MechRecord),
190 Table(MechTable),
191 Tuple(MechTuple),
192 Enum(Box<MechEnum>),
193 Id(u64),
194 Index(Ref<usize>),
195 MutableReference(MutableReference),
196 Kind(ValueKind),
197 IndexAll,
198 Empty
199}
200
201impl fmt::Display for Value {
202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203 self.pretty_print().fmt(f)
204 }
205}
206
207impl Hash for Value {
208 fn hash<H: Hasher>(&self, state: &mut H) {
209 match self {
210 Value::Id(x) => x.hash(state),
211 Value::Kind(x) => x.hash(state),
212 Value::U8(x) => x.borrow().hash(state),
213 Value::U16(x) => x.borrow().hash(state),
214 Value::U32(x) => x.borrow().hash(state),
215 Value::U64(x) => x.borrow().hash(state),
216 Value::U128(x) => x.borrow().hash(state),
217 Value::I8(x) => x.borrow().hash(state),
218 Value::I16(x) => x.borrow().hash(state),
219 Value::I32(x) => x.borrow().hash(state),
220 Value::I64(x) => x.borrow().hash(state),
221 Value::I128(x) => x.borrow().hash(state),
222 Value::F32(x) => x.borrow().hash(state),
223 Value::F64(x) => x.borrow().hash(state),
224 Value::Index(x)=> x.borrow().hash(state),
225 Value::Bool(x) => x.borrow().hash(state),
226 Value::Atom(x) => x.hash(state),
227 Value::Set(x) => x.hash(state),
228 Value::Map(x) => x.hash(state),
229 Value::Table(x) => x.hash(state),
230 Value::Tuple(x) => x.hash(state),
231 Value::Record(x) => x.hash(state),
232 Value::Enum(x) => x.hash(state),
233 Value::String(x) => x.borrow().hash(state),
234 Value::MatrixBool(x) => x.hash(state),
235 Value::MatrixIndex(x) => x.hash(state),
236 Value::MatrixU8(x) => x.hash(state),
237 Value::MatrixU16(x) => x.hash(state),
238 Value::MatrixU32(x) => x.hash(state),
239 Value::MatrixU64(x) => x.hash(state),
240 Value::MatrixU128(x) => x.hash(state),
241 Value::MatrixI8(x) => x.hash(state),
242 Value::MatrixI16(x) => x.hash(state),
243 Value::MatrixI32(x) => x.hash(state),
244 Value::MatrixI64(x) => x.hash(state),
245 Value::MatrixI128(x) => x.hash(state),
246 Value::MatrixF32(x) => x.hash(state),
247 Value::MatrixF64(x) => x.hash(state),
248 Value::MatrixString(x) => x.hash(state),
249 Value::MatrixValue(x) => x.hash(state),
250 Value::MutableReference(x) => x.borrow().hash(state),
251 Value::Empty => Value::Empty.hash(state),
252 Value::IndexAll => Value::IndexAll.hash(state),
253 }
254 }
255}
256
257impl Value {
258
259 pub fn size_of(&self) -> usize {
260 match self {
261 Value::U8(x) => 1,
262 Value::U16(x) => 2,
263 Value::U32(x) => 4,
264 Value::U64(x) => 8,
265 Value::U128(x) => 16,
266 Value::I8(x) => 1,
267 Value::I16(x) => 2,
268 Value::I32(x) => 4,
269 Value::I64(x) => 8,
270 Value::I128(x) => 16,
271 Value::F32(x) => 4,
272 Value::F64(x) => 8,
273 Value::Bool(x) => 1,
274 Value::MatrixIndex(x) =>x.size_of(),
275 Value::MatrixBool(x) =>x.size_of(),
276 Value::MatrixU8(x) => x.size_of(),
277 Value::MatrixU16(x) => x.size_of(),
278 Value::MatrixU32(x) => x.size_of(),
279 Value::MatrixU64(x) => x.size_of(),
280 Value::MatrixU128(x) => x.size_of(),
281 Value::MatrixI8(x) => x.size_of(),
282 Value::MatrixI16(x) => x.size_of(),
283 Value::MatrixI32(x) => x.size_of(),
284 Value::MatrixI64(x) => x.size_of(),
285 Value::MatrixI128(x) => x.size_of(),
286 Value::MatrixF32(x) => x.size_of(),
287 Value::MatrixF64(x) => x.size_of(),
288 Value::MatrixValue(x) => x.size_of(),
289 Value::MatrixString(x) => x.size_of(),
290 Value::String(x) => x.borrow().len(),
291 Value::Atom(x) => 8,
292 Value::Set(x) => x.size_of(),
293 Value::Map(x) => x.size_of(),
294 Value::Table(x) => x.size_of(),
295 Value::Record(x) => x.size_of(),
296 Value::Tuple(x) => x.size_of(),
297 Value::Enum(x) => x.size_of(),
298 Value::MutableReference(x) => x.borrow().size_of(),
299 Value::Id(_) => 8,
300 Value::Index(x) => 8,
301 Value::Kind(_) => 0, Value::Empty => 0,
303 Value::IndexAll => 0, }
305 }
306
307 pub fn to_html(&self) -> String {
308 match self {
309 Value::U8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
310 Value::U16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
311 Value::U32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
312 Value::U64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
313 Value::I8(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
314 Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
315 Value::I16(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
316 Value::I32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
317 Value::I64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
318 Value::I128(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
319 Value::F32(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
320 Value::F64(n) => format!("<span class='mech-number'>{}</span>", n.borrow()),
321 Value::String(s) => format!("<span class='mech-string'>\"{}\"</span>", s.borrow()),
322 Value::Bool(b) => format!("<span class='mech-bool'>{}</span>", b.borrow()),
323 Value::MatrixU8(m) => m.to_html(),
324 Value::MatrixU16(m) => m.to_html(),
325 Value::MatrixU32(m) => m.to_html(),
326 Value::MatrixU64(m) => m.to_html(),
327 Value::MatrixU128(m) => m.to_html(),
328 Value::MatrixI8(m) => m.to_html(),
329 Value::MatrixI16(m) => m.to_html(),
330 Value::MatrixI32(m) => m.to_html(),
331 Value::MatrixI64(m) => m.to_html(),
332 Value::MatrixI128(m) => m.to_html(),
333 Value::MatrixF64(m) => m.to_html(),
334 Value::MatrixF32(m) => m.to_html(),
335 Value::MatrixIndex(m) => m.to_html(),
336 Value::MatrixBool(m) => m.to_html(),
337 Value::MatrixString(m) => m.to_html(),
338 Value::MatrixValue(m) => m.to_html(),
339 Value::MutableReference(m) => {
340 let inner = m.borrow();
341 format!("<span class='mech-reference'>{}</span>", inner.to_html())
342 },
343 Value::Atom(a) => format!("<span class=\"mech-atom\"><span class=\"mech-atom-grave\">`</span><span class=\"mech-atom-name\">{}</span></span>",a),
344 Value::Set(s) => s.to_html(),
345 Value::Map(m) => m.to_html(),
346 Value::Table(t) => t.to_html(),
347 Value::Record(r) => r.to_html(),
348 Value::Tuple(t) => t.to_html(),
349 Value::Enum(e) => e.to_html(),
350 _ => "".to_string(),
351 }
352 }
353
354 pub fn pretty_print(&self) -> String {
355 let mut builder = Builder::default();
356 match self {
357 Value::U8(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
358 Value::U16(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
359 Value::U32(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
360 Value::U64(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
361 Value::U128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
362 Value::I8(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
363 Value::I16(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
364 Value::I32(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
365 Value::I64(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
366 Value::I128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
367 Value::F32(x) => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
368 Value::F64(x) => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
369 Value::Bool(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
370 Value::Index(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
371 Value::Atom(x) => {builder.push_record(vec![format!("{}",x)]);},
372 Value::Set(x) => {return x.pretty_print();}
373 Value::Map(x) => {return x.pretty_print();}
374 Value::String(x) => {return format!("\"{}\"",x.borrow().clone());},
375 Value::Table(x) => {return x.pretty_print();},
376 Value::Tuple(x) => {return x.pretty_print();},
377 Value::Record(x) => {return x.pretty_print();},
378 Value::Enum(x) => {return x.pretty_print();},
379 Value::MatrixIndex(x) => {return x.pretty_print();}
380 Value::MatrixBool(x) => {return x.pretty_print();}
381 Value::MatrixU8(x) => {return x.pretty_print();},
382 Value::MatrixU16(x) => {return x.pretty_print();},
383 Value::MatrixU32(x) => {return x.pretty_print();},
384 Value::MatrixU64(x) => {return x.pretty_print();},
385 Value::MatrixU128(x) => {return x.pretty_print();},
386 Value::MatrixI8(x) => {return x.pretty_print();},
387 Value::MatrixI16(x) => {return x.pretty_print();},
388 Value::MatrixI32(x) => {return x.pretty_print();},
389 Value::MatrixI64(x) => {return x.pretty_print();},
390 Value::MatrixI128(x) => {return x.pretty_print();},
391 Value::MatrixF32(x) => {return x.pretty_print();},
392 Value::MatrixF64(x) => {return x.pretty_print();},
393 Value::MatrixValue(x) => {return x.pretty_print();},
394 Value::MatrixString(x) => {return x.pretty_print();},
395 Value::MutableReference(x) => {return x.borrow().pretty_print();},
396 Value::Empty => builder.push_record(vec!["_"]),
397 Value::IndexAll => builder.push_record(vec![":"]),
398 Value::Id(x) => builder.push_record(vec![format!("{:?}",humanize(x))]),
399 Value::Kind(x) => builder.push_record(vec![format!("{:?}",x)]),
400 };
401 let value_style = Style::empty()
402 .top(' ')
403 .left(' ')
404 .right(' ')
405 .bottom(' ')
406 .vertical(' ')
407 .intersection_bottom(' ')
408 .corner_top_left(' ')
409 .corner_top_right(' ')
410 .corner_bottom_left(' ')
411 .corner_bottom_right(' ');
412 let mut table = builder.build();
413 table.with(value_style);
414 format!("{table}")
415 }
416
417 pub fn shape(&self) -> Vec<usize> {
418 match self {
419 Value::U8(x) => vec![1,1],
420 Value::U16(x) => vec![1,1],
421 Value::U32(x) => vec![1,1],
422 Value::U64(x) => vec![1,1],
423 Value::U128(x) => vec![1,1],
424 Value::I8(x) => vec![1,1],
425 Value::I16(x) => vec![1,1],
426 Value::I32(x) => vec![1,1],
427 Value::I64(x) => vec![1,1],
428 Value::I128(x) => vec![1,1],
429 Value::F32(x) => vec![1,1],
430 Value::F64(x) => vec![1,1],
431 Value::Index(x) => vec![1,1],
432 Value::String(x) => vec![1,1],
433 Value::Bool(x) => vec![1,1],
434 Value::Atom(x) => vec![1,1],
435 Value::MatrixIndex(x) => x.shape(),
436 Value::MatrixBool(x) => x.shape(),
437 Value::MatrixU8(x) => x.shape(),
438 Value::MatrixU16(x) => x.shape(),
439 Value::MatrixU32(x) => x.shape(),
440 Value::MatrixU64(x) => x.shape(),
441 Value::MatrixU128(x) => x.shape(),
442 Value::MatrixI8(x) => x.shape(),
443 Value::MatrixI16(x) => x.shape(),
444 Value::MatrixI32(x) => x.shape(),
445 Value::MatrixI64(x) => x.shape(),
446 Value::MatrixI128(x) => x.shape(),
447 Value::MatrixF32(x) => x.shape(),
448 Value::MatrixF64(x) => x.shape(),
449 Value::MatrixString(x) => x.shape(),
450 Value::MatrixValue(x) => x.shape(),
451 Value::Enum(x) => vec![1,1],
452 Value::Table(x) => x.shape(),
453 Value::Set(x) => vec![1,x.set.len()],
454 Value::Map(x) => vec![1,x.map.len()],
455 Value::Record(x) => x.shape(),
456 Value::Tuple(x) => vec![1,x.size()],
457 Value::MutableReference(x) => x.borrow().shape(),
458 Value::Empty => vec![0,0],
459 Value::IndexAll => vec![0,0],
460 Value::Kind(_) => vec![0,0],
461 Value::Id(x) => vec![0,0],
462 }
463 }
464
465 pub fn kind(&self) -> ValueKind {
466 match self {
467 Value::U8(_) => ValueKind::U8,
468 Value::U16(_) => ValueKind::U16,
469 Value::U32(_) => ValueKind::U32,
470 Value::U64(_) => ValueKind::U64,
471 Value::U128(_) => ValueKind::U128,
472 Value::I8(_) => ValueKind::I8,
473 Value::I16(_) => ValueKind::I16,
474 Value::I32(_) => ValueKind::I32,
475 Value::I64(_) => ValueKind::I64,
476 Value::I128(_) => ValueKind::I128,
477 Value::F32(_) => ValueKind::F32,
478 Value::F64(_) => ValueKind::F64,
479 Value::String(_) => ValueKind::String,
480 Value::Bool(_) => ValueKind::Bool,
481 Value::Atom(x) => ValueKind::Atom(*x),
482 Value::MatrixIndex(x) => ValueKind::Matrix(Box::new(ValueKind::Index),x.shape()),
483 Value::MatrixBool(x) => ValueKind::Matrix(Box::new(ValueKind::Bool),x.shape()),
484 Value::MatrixU8(x) => ValueKind::Matrix(Box::new(ValueKind::U8),x.shape()),
485 Value::MatrixU16(x) => ValueKind::Matrix(Box::new(ValueKind::U16),x.shape()),
486 Value::MatrixU32(x) => ValueKind::Matrix(Box::new(ValueKind::U32),x.shape()),
487 Value::MatrixU64(x) => ValueKind::Matrix(Box::new(ValueKind::U64),x.shape()),
488 Value::MatrixU128(x) => ValueKind::Matrix(Box::new(ValueKind::U128),x.shape()),
489 Value::MatrixI8(x) => ValueKind::Matrix(Box::new(ValueKind::I8),x.shape()),
490 Value::MatrixI16(x) => ValueKind::Matrix(Box::new(ValueKind::I16),x.shape()),
491 Value::MatrixI32(x) => ValueKind::Matrix(Box::new(ValueKind::I32),x.shape()),
492 Value::MatrixI64(x) => ValueKind::Matrix(Box::new(ValueKind::I64),x.shape()),
493 Value::MatrixI128(x) => ValueKind::Matrix(Box::new(ValueKind::U128,),x.shape()),
494 Value::MatrixF32(x) => ValueKind::Matrix(Box::new(ValueKind::F32),x.shape()),
495 Value::MatrixF64(x) => ValueKind::Matrix(Box::new(ValueKind::F64),x.shape()),
496 Value::MatrixString(x) => ValueKind::Matrix(Box::new(ValueKind::String),x.shape()),
497 Value::MatrixValue(x) => ValueKind::Matrix(Box::new(ValueKind::Any),x.shape()),
498 Value::Table(x) => x.kind(),
499 Value::Set(x) => x.kind(),
500 Value::Map(x) => x.kind(),
501 Value::Record(x) => x.kind(),
502 Value::Tuple(x) => x.kind(),
503 Value::Enum(x) => x.kind(),
504 Value::MutableReference(x) => ValueKind::Reference(Box::new(x.borrow().kind())),
505 Value::Empty => ValueKind::Empty,
506 Value::IndexAll => ValueKind::Empty,
507 Value::Id(x) => ValueKind::Id,
508 Value::Index(x) => ValueKind::Index,
509 Value::Kind(x) => x.clone(),
510 }
511 }
512
513 pub fn is_matrix(&self) -> bool {
514 match self {
515 Value::MatrixIndex(_) | Value::MatrixBool(_) | Value::MatrixU8(_) |
516 Value::MatrixU16(_) | Value::MatrixU32(_) | Value::MatrixU64(_) |
517 Value::MatrixU128(_) | Value::MatrixI8(_) | Value::MatrixI16(_) |
518 Value::MatrixI32(_) | Value::MatrixI64(_) | Value::MatrixI128(_) |
519 Value::MatrixF32(_) | Value::MatrixF64(_) | Value::MatrixString(_) |
520 Value::MatrixValue(_) => true,
521 _ => false,
522 }
523 }
524
525 pub fn is_scalar(&self) -> bool {
526 match self {
527 Value::U8(_) | Value::U16(_) | Value::U32(_) |
528 Value::U64(_) | Value::U128(_) | Value::I8(_) |
529 Value::I16(_) | Value::I32(_) | Value::I64(_) |
530 Value::I128(_) | Value::F32(_) | Value::F64(_) |
531 Value::Bool(_) | Value::String(_) |
532 Value::Atom(_) | Value::Index(_) => true,
533 _ => false,
534 }
535 }
536
537 pub fn as_bool(&self) -> Option<Ref<bool>> {if let Value::Bool(v) = self { Some(v.clone()) } else if let Value::MutableReference(val) = self { val.borrow().as_bool() } else { None }}
538
539 impl_as_type!(i8);
540 impl_as_type!(i16);
541 impl_as_type!(i32);
542 impl_as_type!(i64);
543 impl_as_type!(i128);
544 impl_as_type!(u8);
545 impl_as_type!(u16);
546 impl_as_type!(u32);
547 impl_as_type!(u64);
548 impl_as_type!(u128);
549
550 pub fn as_string(&self) -> Option<Ref<String>> {
551 match self {
552 Value::String(v) => Some(v.clone()),
553 Value::U8(v) => Some(new_ref(v.borrow().to_string())),
554 Value::U16(v) => Some(new_ref(v.borrow().to_string())),
555 Value::U32(v) => Some(new_ref(v.borrow().to_string())),
556 Value::U64(v) => Some(new_ref(v.borrow().to_string())),
557 Value::U128(v) => Some(new_ref(v.borrow().to_string())),
558 Value::I8(v) => Some(new_ref(v.borrow().to_string())),
559 Value::I16(v) => Some(new_ref(v.borrow().to_string())),
560 Value::I32(v) => Some(new_ref(v.borrow().to_string())),
561 Value::I64(v) => Some(new_ref(v.borrow().to_string())),
562 Value::I128(v) => Some(new_ref(v.borrow().to_string())),
563 Value::F32(v) => Some(new_ref(format!("{}", v.borrow().0))),
564 Value::F64(v) => Some(new_ref(format!("{}", v.borrow().0))),
565 Value::Bool(v) => Some(new_ref(format!("{}", v.borrow()))),
566 Value::MutableReference(val) => val.borrow().as_string(),
567 _ => None,
568 }
569 }
570
571 pub fn as_f32(&self) -> Option<Ref<F32>> {
572 match self {
573 Value::U8(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
574 Value::U16(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
575 Value::U32(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
576 Value::U64(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
577 Value::U128(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
578 Value::I8(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
579 Value::I16(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
580 Value::I32(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
581 Value::I64(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
582 Value::I128(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
583 Value::F32(v) => Some(new_ref(F32::new((*v.borrow()).0 as f32))),
584 Value::F64(v) => Some(new_ref(F32::new((*v.borrow()).0 as f32))),
585 Value::MutableReference(val) => val.borrow().as_f32(),
586 _ => None,
587 }
588 }
589
590 pub fn as_f64(&self) -> Option<Ref<F64>> {
591 match self {
592 Value::U8(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
593 Value::U16(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
594 Value::U32(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
595 Value::U64(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
596 Value::U128(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
597 Value::I8(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
598 Value::I16(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
599 Value::I32(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
600 Value::I64(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
601 Value::I128(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
602 Value::F64(v) => Some(new_ref(F64::new((*v.borrow()).0 as f64))),
603 Value::F64(v) => Some(new_ref(F64::new((*v.borrow()).0 as f64))),
604 Value::MutableReference(val) => val.borrow().as_f64(),
605 _ => None,
606 }
607 }
608
609 pub fn as_vecbool(&self) -> Option<Vec<bool>> {if let Value::MatrixBool(v) = self { Some(v.as_vec()) } else if let Value::Bool(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecbool() } else { None }}
610
611 pub fn as_vecf64(&self) -> Option<Vec<F64>> { if let Value::MatrixF64(v) = self { Some(v.as_vec()) } else if let Value::F64(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecf64() } else if let Some(v) = self.as_f64() { Some(vec![v.borrow().clone()]) } else { None } }
612 pub fn as_vecf32(&self) -> Option<Vec<F32>> { if let Value::MatrixF32(v) = self { Some(v.as_vec()) } else if let Value::F32(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecf32() } else if let Some(v) = self.as_f32() { Some(vec![v.borrow().clone()]) } else { None } }
613
614 pub fn as_vecu8(&self) -> Option<Vec<u8>> { if let Value::MatrixU8(v) = self { Some(v.as_vec()) } else if let Value::U8(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu8() } else if let Some(v) = self.as_u8() { Some(vec![v.borrow().clone()]) } else { None } }
615 pub fn as_vecu16(&self) -> Option<Vec<u16>> { if let Value::MatrixU16(v) = self { Some(v.as_vec()) } else if let Value::U16(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu16() } else if let Some(v) = self.as_u16() { Some(vec![v.borrow().clone()]) } else { None } }
616 pub fn as_vecu32(&self) -> Option<Vec<u32>> { if let Value::MatrixU32(v) = self { Some(v.as_vec()) } else if let Value::U32(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu32() } else if let Some(v) = self.as_u32() { Some(vec![v.borrow().clone()]) } else { None } }
617 pub fn as_vecu64(&self) -> Option<Vec<u64>> { if let Value::MatrixU64(v) = self { Some(v.as_vec()) } else if let Value::U64(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu64() } else if let Some(v) = self.as_u64() { Some(vec![v.borrow().clone()]) } else { None } }
618 pub fn as_vecu128(&self) -> Option<Vec<u128>> { if let Value::MatrixU128(v) = self { Some(v.as_vec()) } else if let Value::U128(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecu128() } else if let Some(v) = self.as_u128() { Some(vec![v.borrow().clone()]) } else { None } }
619
620 pub fn as_veci8(&self) -> Option<Vec<i8>> { if let Value::MatrixI8(v) = self { Some(v.as_vec()) } else if let Value::I8(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci8() } else if let Some(v) = self.as_i8() { Some(vec![v.borrow().clone()]) } else { None } }
621 pub fn as_veci16(&self) -> Option<Vec<i16>> { if let Value::MatrixI16(v) = self { Some(v.as_vec()) } else if let Value::I16(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci16() } else if let Some(v) = self.as_i16() { Some(vec![v.borrow().clone()]) } else { None } }
622 pub fn as_veci32(&self) -> Option<Vec<i32>> { if let Value::MatrixI32(v) = self { Some(v.as_vec()) } else if let Value::I32(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci32() } else if let Some(v) = self.as_i32() { Some(vec![v.borrow().clone()]) } else { None } }
623 pub fn as_veci64(&self) -> Option<Vec<i64>> { if let Value::MatrixI64(v) = self { Some(v.as_vec()) } else if let Value::I64(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci64() } else if let Some(v) = self.as_i64() { Some(vec![v.borrow().clone()]) } else { None } }
624 pub fn as_veci128(&self) -> Option<Vec<i128>> { if let Value::MatrixI128(v) = self { Some(v.as_vec()) } else if let Value::I128(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_veci128() } else if let Some(v) = self.as_i128() { Some(vec![v.borrow().clone()]) } else { None } }
625
626 pub fn as_vecstring(&self) -> Option<Vec<String>> {if let Value::MatrixString(v) = self { Some(v.as_vec()) } else if let Value::String(v) = self { Some(vec![v.borrow().clone()]) } else if let Value::MutableReference(val) = self { val.borrow().as_vecstring() } else { None }}
627
628
629 pub fn as_vecusize(&self) -> Option<Vec<usize>> {
630 match self {
631 Value::MatrixIndex(v) => Some(v.as_vec()),
632 Value::MatrixI64(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
633 Value::MatrixF64(v) => Some(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
634 Value::MutableReference(x) => x.borrow().as_vecusize(),
635 Value::MatrixBool(_) => None,
636 Value::Bool(_) => None,
637 _ => todo!(),
638 }
639 }
640
641 pub fn as_index(&self) -> MResult<Value> {
642 match self.as_usize() {
643 Some(ix) => Ok(Value::Index(new_ref(ix))),
644 None => match self.as_vecusize() {
645 Some(x) => {
646 let shape = self.shape();
647 let out = Value::MatrixIndex(usize::to_matrix(x, shape[0] * shape[1],1 ));
648 Ok(out)
649 },
650 None => match self.as_vecbool() {
651 Some(x) => {
652 let shape = self.shape();
653 let out = match (shape[0], shape[1]) {
654 (1,1) => Value::Bool(new_ref(x[0])),
655 (1,n) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
656 (m,1) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
657 (m,n) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
658 };
659 Ok(out)
660 }
661 None => match self.as_bool() {
662 Some(x) => Ok(Value::Bool(x)),
663 None => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledIndexKind}),
664 }
665 }
666 }
667 }
668 }
669
670 pub fn as_usize(&self) -> Option<usize> {
671 match self {
672 Value::Index(v) => Some(*v.borrow()),
673 Value::U8(v) => Some(*v.borrow() as usize),
674 Value::U16(v) => Some(*v.borrow() as usize),
675 Value::U32(v) => Some(*v.borrow() as usize),
676 Value::U64(v) => Some(*v.borrow() as usize),
677 Value::U128(v) => Some(*v.borrow() as usize),
678 Value::I8(v) => Some(*v.borrow() as usize),
679 Value::I16(v) => Some(*v.borrow() as usize),
680 Value::I32(v) => Some(*v.borrow() as usize),
681 Value::I64(v) => Some(*v.borrow() as usize),
682 Value::I128(v) => Some(*v.borrow() as usize),
683 Value::F32(v) => Some((*v.borrow()).0 as usize),
684 Value::F64(v) => Some((*v.borrow()).0 as usize),
685 Value::Id(v) => Some(*v as usize),
686 Value::MutableReference(v) => v.borrow().as_usize(),
687 _ => None,
688 }
689 }
690
691}
692
693pub trait ToIndex {
694 fn to_index(&self) -> Value;
695}
696
697impl ToIndex for Ref<Vec<i64>> { fn to_index(&self) -> Value { (*self.borrow()).iter().map(|x| *x as usize).collect::<Vec<usize>>().to_value() } }
698
699pub trait ToValue {
700 fn to_value(&self) -> Value;
701}
702
703impl ToValue for Vec<usize> {
704 fn to_value(&self) -> Value {
705 match self.len() {
706 1 => Value::Index(new_ref(self[0].clone())),
707 n => Value::MatrixIndex(Matrix::DVector(new_ref(DVector::from_vec(self.clone())))),
711 }
712 }
713}
714
715impl ToValue for Ref<usize> { fn to_value(&self) -> Value { Value::Index(self.clone()) } }
716impl ToValue for Ref<u8> { fn to_value(&self) -> Value { Value::U8(self.clone()) } }
717impl ToValue for Ref<u16> { fn to_value(&self) -> Value { Value::U16(self.clone()) } }
718impl ToValue for Ref<u32> { fn to_value(&self) -> Value { Value::U32(self.clone()) } }
719impl ToValue for Ref<u64> { fn to_value(&self) -> Value { Value::U64(self.clone()) } }
720impl ToValue for Ref<u128> { fn to_value(&self) -> Value { Value::U128(self.clone()) } }
721impl ToValue for Ref<i8> { fn to_value(&self) -> Value { Value::I8(self.clone()) } }
722impl ToValue for Ref<i16> { fn to_value(&self) -> Value { Value::I16(self.clone()) } }
723impl ToValue for Ref<i32> { fn to_value(&self) -> Value { Value::I32(self.clone()) } }
724impl ToValue for Ref<i64> { fn to_value(&self) -> Value { Value::I64(self.clone()) } }
725impl ToValue for Ref<i128> { fn to_value(&self) -> Value { Value::I128(self.clone()) } }
726impl ToValue for Ref<F32> { fn to_value(&self) -> Value { Value::F32(self.clone()) } }
727impl ToValue for Ref<F64> { fn to_value(&self) -> Value { Value::F64(self.clone()) } }
728impl ToValue for Ref<bool> { fn to_value(&self) -> Value { Value::Bool(self.clone()) } }
729impl ToValue for Ref<String> { fn to_value(&self) -> Value { Value::String(self.clone()) } }
730
731macro_rules! to_value_matrix {
732 ($($nd_matrix_kind:ident, $matrix_kind:ident, $base_type:ty),+ $(,)?) => {
733 $(
734 impl ToValue for Ref<$nd_matrix_kind<$base_type>> {
735 fn to_value(&self) -> Value {
736 Value::$matrix_kind(Matrix::<$base_type>::$nd_matrix_kind(self.clone()))
737 }
738 }
739 )+
740 };}
741
742macro_rules! impl_to_value_matrix {
743 ($matrix_kind:ident) => {
744 to_value_matrix!(
745 $matrix_kind, MatrixIndex, usize,
746 $matrix_kind, MatrixBool, bool,
747 $matrix_kind, MatrixI8, i8,
748 $matrix_kind, MatrixI16, i16,
749 $matrix_kind, MatrixI32, i32,
750 $matrix_kind, MatrixI64, i64,
751 $matrix_kind, MatrixI128, i128,
752 $matrix_kind, MatrixU8, u8,
753 $matrix_kind, MatrixU16, u16,
754 $matrix_kind, MatrixU32, u32,
755 $matrix_kind, MatrixU64, u64,
756 $matrix_kind, MatrixU128, u128,
757 $matrix_kind, MatrixF32, F32,
758 $matrix_kind, MatrixF64, F64,
759 $matrix_kind, MatrixString, String,
760 );
761 }
762}
763
764impl_to_value_matrix!(Matrix2x3);
765impl_to_value_matrix!(Matrix3x2);
766impl_to_value_matrix!(Matrix1);
767impl_to_value_matrix!(Matrix2);
768impl_to_value_matrix!(Matrix3);
769impl_to_value_matrix!(Matrix4);
770impl_to_value_matrix!(Vector2);
771impl_to_value_matrix!(Vector3);
772impl_to_value_matrix!(Vector4);
773impl_to_value_matrix!(RowVector2);
774impl_to_value_matrix!(RowVector3);
775impl_to_value_matrix!(RowVector4);
776impl_to_value_matrix!(RowDVector);
777impl_to_value_matrix!(DVector);
778impl_to_value_matrix!(DMatrix);
779
780#[derive(Clone, Debug, PartialEq, Eq)]
783pub struct MechSet {
784 pub kind: ValueKind,
785 pub num_elements: usize,
786 pub set: IndexSet<Value>,
787}
788
789impl MechSet {
790
791 pub fn to_html(&self) -> String {
792 let mut src = String::new();
793 for (i, element) in self.set.iter().enumerate() {
794 let e = element.to_html();
795 if i == 0 {
796 src = format!("{}", e);
797 } else {
798 src = format!("{}, {}", src, e);
799 }
800 }
801 format!("<span class=\"mech-set\"><span class=\"mech-start-brace\">{{</span>{}<span class=\"mech-end-brace\">}}</span></span>",src)
802 }
803
804 pub fn kind(&self) -> ValueKind {
805 ValueKind::Set(Box::new(self.kind.clone()), self.num_elements)
806 }
807
808 pub fn size_of(&self) -> usize {
809 self.set.iter().map(|x| x.size_of()).sum()
810 }
811
812 pub fn from_vec(vec: Vec<Value>) -> MechSet {
813 let mut set = IndexSet::new();
814 for v in vec {
815 set.insert(v);
816 }
817 let kind = if set.len() > 0 { set.iter().next().unwrap().kind() } else { ValueKind::Empty };
818 MechSet{
819 kind,
820 num_elements: set.len(),
821 set}
822 }
823
824 pub fn pretty_print(&self) -> String {
825 let mut builder = Builder::default();
826 let mut element_strings = vec![];
827 for x in self.set.iter() {
828 element_strings.push(x.pretty_print());
829 }
830 builder.push_record(element_strings);
831
832 let style = Style::empty()
833 .top(' ')
834 .left('║')
835 .right('║')
836 .bottom(' ')
837 .vertical(' ')
838 .intersection_bottom(' ')
839 .corner_top_left('╔')
840 .corner_top_right('╗')
841 .corner_bottom_left('╚')
842 .corner_bottom_right('╝');
843 let mut table = builder.build();
844 table.with(style);
845 format!("{table}")
846 }
847
848}
849
850impl Hash for MechSet {
851 fn hash<H: Hasher>(&self, state: &mut H) {
852 for x in self.set.iter() {
853 x.hash(state)
854 }
855 }
856}
857
858#[derive(Clone, Debug, PartialEq, Eq)]
861pub struct MechMap {
862 pub key_kind: ValueKind,
863 pub value_kind: ValueKind,
864 pub num_elements: usize,
865 pub map: IndexMap<Value,Value>,
866}
867
868impl MechMap {
869
870 pub fn to_html(&self) -> String {
871 let mut src = String::new();
872 for (i, (key, value)) in self.map.iter().enumerate() {
873 let k = key.to_html();
874 let v = value.to_html();
875 if i == 0 {
876 src = format!("{}: {}", k, v);
877 } else {
878 src = format!("{}, {}: {}", src, k, v);
879 }
880 }
881 format!("<span class=\"mech-map\"><span class=\"mech-start-brace\">{{</span>{}<span class=\"mech-end-brace\">}}</span></span>",src)
882 }
883
884 pub fn kind(&self) -> ValueKind {
885 ValueKind::Map(Box::new(self.key_kind.clone()), Box::new(self.value_kind.clone()))
886 }
887
888 pub fn size_of(&self) -> usize {
889 self.map.iter().map(|(k,v)| k.size_of() + v.size_of()).sum()
890 }
891
892 pub fn pretty_print(&self) -> String {
893 let mut builder = Builder::default();
894 let mut element_strings = vec![];
895 let mut key_strings = vec![];
896 for (k,v) in self.map.iter() {
897 element_strings.push(v.pretty_print());
898 key_strings.push(k.pretty_print());
899 }
900 builder.push_record(key_strings);
901 builder.push_record(element_strings);
902 let mut table = builder.build();
903 table.with(Style::modern_rounded());
904 format!("{table}")
905 }
906
907 pub fn from_vec(vec: Vec<(Value,Value)>) -> MechMap {
908 let mut map = IndexMap::new();
909 for (k,v) in vec {
910 map.insert(k,v);
911 }
912 MechMap{
913 key_kind: map.keys().next().unwrap().kind(),
914 value_kind: map.values().next().unwrap().kind(),
915 num_elements: map.len(),
916 map}
917 }
918}
919
920impl Hash for MechMap {
921 fn hash<H: Hasher>(&self, state: &mut H) {
922 for x in self.map.iter() {
923 x.hash(state)
924 }
925 }
926}
927
928#[derive(Clone, Debug, PartialEq, Eq)]
931pub struct MechTable {
932 rows: usize,
933 cols: usize,
934 data: IndexMap<Value,(ValueKind,Matrix<Value>)>,
935 col_names: HashMap<Value,String>,
936}
937
938impl MechTable {
939
940 pub fn to_html(&self) -> String {
941 let mut table = String::new();
942
943 table.push_str("<table class=\"mech-table\">");
945
946 table.push_str("<thead class=\"mech-table-header\"><tr>");
948 for key in self.data.keys() {
949 let col_name = self.col_names.get(key).unwrap();
950 table.push_str(&format!("<th class=\"mech-table-field\">{}</th>", col_name));
951 }
952 table.push_str("</tr></thead>");
953
954 table.push_str("<tbody class=\"mech-table-body\">");
956
957 for row_idx in 0..self.rows {
958 table.push_str("<tr class=\"mech-table-row\">");
959 for (_key, (_kind, matrix)) in self.data.iter() {
960 let value = matrix.index1d(row_idx);
961 table.push_str(&format!("<td class=\"mech-table-column\">{}</td>", value));
962 }
963 table.push_str("</tr>");
964 }
965
966 table.push_str("</tbody></table>");
967 table
968 }
969
970 pub fn new(rows: usize, cols: usize, data: IndexMap<Value,(ValueKind,Matrix<Value>)>, col_names: HashMap<Value,String>) -> MechTable {
971 MechTable{rows, cols, data, col_names}
972 }
973
974 pub fn kind(&self) -> ValueKind {
975 ValueKind::Table(
976 self.data.iter().map(|(_,v)| v.0.clone()).collect(),
977 self.rows)
978 }
979
980 pub fn size_of(&self) -> usize {
981 self.data.iter().map(|(_,(_,v))| v.size_of()).sum()
982 }
983
984 pub fn rows(&self) -> usize {
985 self.rows
986 }
987
988 pub fn cols(&self) -> usize {
989 self.cols
990 }
991
992 pub fn get(&self, key: &Value) -> Option<&(ValueKind,Matrix<Value>)> {
993 self.data.get(key)
994 }
995
996 pub fn pretty_print(&self) -> String {
997 let mut builder = Builder::default();
998 for (k,(knd,val)) in &self.data {
999 let name = self.col_names.get(k).unwrap();
1000 let val_string: String = val.as_vec().iter()
1001 .map(|x| x.pretty_print())
1002 .collect::<Vec<String>>()
1003 .join("\n");
1004 let mut col_string = vec![format!("{}<{}>", name.to_string(), knd), val_string];
1005 builder.push_column(col_string);
1006 }
1007 let mut table = builder.build();
1008 table.with(Style::modern_rounded());
1009 format!("{table}")
1010 }
1011
1012 pub fn shape(&self) -> Vec<usize> {
1013 vec![self.rows,self.cols]
1014 }
1015}
1016
1017impl Hash for MechTable {
1018 fn hash<H: Hasher>(&self, state: &mut H) {
1019 for (k,(knd,val)) in self.data.iter() {
1020 k.hash(state);
1021 knd.hash(state);
1022 val.hash(state);
1023 }
1024 }
1025}
1026
1027#[derive(Clone, Debug, PartialEq, Eq)]
1030pub struct MechRecord {
1031 pub cols: usize,
1032 pub kinds: Vec<ValueKind>,
1033 pub data: IndexMap<u64,Value>,
1034 pub field_names: HashMap<u64,String>,
1035}
1036
1037impl MechRecord {
1038
1039 pub fn to_html(&self) -> String {
1040 let mut bindings = Vec::new();
1041
1042 for (key, value) in &self.data {
1043 let name = self.field_names.get(key).unwrap();
1044
1045 let binding_html = format!(
1046 "<span class=\"mech-binding\">\
1047 <span class=\"mech-binding-name\">{}</span>\
1048 <span class=\"mech-binding-colon-op\">:</span>\
1049 <span class=\"mech-binding-value\">{}</span>\
1050 </span>",
1051 name,
1052 value.to_html(),
1053 );
1054
1055 bindings.push(binding_html);
1056 }
1057
1058 format!(
1059 "<span class=\"mech-record\">\
1060 <span class=\"mech-start-brace\">{{</span>{}<span class=\"mech-end-brace\">}}</span>\
1061 </span>",
1062 bindings.join("<span class=\"mech-separator\">, </span>")
1063 )
1064 }
1065
1066 pub fn get(&self, key: &u64) -> Option<&Value> {
1067 self.data.get(key)
1068 }
1069
1070 pub fn from_vec(vec: Vec<((u64,String),Value)>) -> MechRecord {
1071 let mut data = IndexMap::new();
1072 let mut field_names = HashMap::new();
1073 for ((k,s),v) in vec {
1074 field_names.insert(k,s);
1075 data.insert(k,v);
1076 }
1077 let kinds = data.iter().map(|(_,v)| v.kind()).collect();
1078 MechRecord{cols: data.len(), kinds, data, field_names}
1079 }
1080
1081 pub fn insert_field(&mut self, key: u64, value: Value) {
1082 self.cols += 1;
1083 self.kinds.push(value.kind());
1084 self.data.insert(key, value);
1085 }
1086
1087 pub fn kind(&self) -> ValueKind {
1088 ValueKind::Record(self.kinds.clone())
1089 }
1090
1091 pub fn size_of(&self) -> usize {
1092 self.data.iter().map(|(_,v)| v.size_of()).sum()
1093 }
1094
1095 pub fn pretty_print(&self) -> String {
1096 let mut builder = Builder::default();
1097 let mut key_strings = vec![];
1098 let mut element_strings = vec![];
1099 for (k,v) in &self.data {
1100 let field_name = self.field_names.get(k).unwrap();
1101 key_strings.push(format!("{}<{}>",field_name, v.kind()));
1102 element_strings.push(v.pretty_print());
1103 }
1104 builder.push_record(key_strings);
1105 builder.push_record(element_strings);
1106 let mut table = builder.build();
1107 table.with(Style::modern_rounded());
1108 format!("{table}")
1109 }
1110
1111 pub fn shape(&self) -> Vec<usize> {
1112 vec![1,self.cols]
1113 }
1114}
1115
1116impl Hash for MechRecord {
1117 fn hash<H: Hasher>(&self, state: &mut H) {
1118 for (k,v) in self.data.iter() {
1119 k.hash(state);
1120 v.hash(state);
1121 }
1122 }
1123}
1124
1125#[derive(Clone, Debug, PartialEq, Eq)]
1128pub struct MechTuple {
1129 pub elements: Vec<Box<Value>>
1130}
1131
1132impl MechTuple {
1133
1134 pub fn to_html(&self) -> String {
1135 let mut elements = Vec::new();
1136 for element in &self.elements {
1137 elements.push(element.to_html());
1138 }
1139 format!("<span class=\"mech-tuple\"><span class=\"mech-start-brace\">(</span>{}<span class=\"mech-end-brace\">)</span></span>", elements.join(", "))
1140 }
1141
1142 pub fn pretty_print(&self) -> String {
1143 let mut builder = Builder::default();
1144 let string_elements: Vec<String> = self.elements.iter().map(|e| e.pretty_print()).collect::<Vec<String>>();
1145 builder.push_record(string_elements);
1146 let mut table = builder.build();
1147 let style = Style::empty()
1148 .top(' ')
1149 .left('│')
1150 .right('│')
1151 .bottom(' ')
1152 .vertical(' ')
1153 .intersection_bottom('ʼ')
1154 .corner_top_left('╭')
1155 .corner_top_right('╮')
1156 .corner_bottom_left('╰')
1157 .corner_bottom_right('╯');
1158 table.with(style);
1159 format!("{table}")
1160 }
1161
1162 pub fn from_vec(elements: Vec<Value>) -> Self {
1163 MechTuple{elements: elements.iter().map(|m| Box::new(m.clone())).collect::<Vec<Box<Value>>>()}
1164 }
1165
1166 pub fn size(&self) -> usize {
1167 self.elements.len()
1168 }
1169
1170 pub fn kind(&self) -> ValueKind {
1171 ValueKind::Tuple(self.elements.iter().map(|x| x.kind()).collect())
1172 }
1173
1174 pub fn size_of(&self) -> usize {
1175 self.elements.iter().map(|x| x.size_of()).sum()
1176 }
1177
1178}
1179
1180impl Hash for MechTuple {
1181 fn hash<H: Hasher>(&self, state: &mut H) {
1182 for x in self.elements.iter() {
1183 x.hash(state)
1184 }
1185 }
1186}
1187
1188#[derive(Clone, Debug, PartialEq, Eq)]
1191pub struct MechEnum {
1192 pub id: u64,
1193 pub variants: Vec<(u64, Option<Value>)>,
1194}
1195
1196impl MechEnum {
1197
1198 pub fn to_html(&self) -> String {
1199 let mut variants = Vec::new();
1200 for (id, value) in &self.variants {
1201 let value_html = match value {
1202 Some(v) => v.to_html(),
1203 None => "None".to_string(),
1204 };
1205 variants.push(format!("<span class=\"mech-enum-variant\">{}: {}</span>", id, value_html));
1206 }
1207 format!("<span class=\"mech-enum\"><span class=\"mech-start-brace\">{{</span>{}<span class=\"mech-end-brace\">}}</span></span>", variants.join(", "))
1208 }
1209
1210 pub fn kind(&self) -> ValueKind {
1211 ValueKind::Enum(self.id)
1212 }
1213
1214 pub fn size_of(&self) -> usize {
1215 self.variants.iter().map(|(_,v)| v.as_ref().map_or(0, |x| x.size_of())).sum()
1216 }
1217
1218 pub fn pretty_print(&self) -> String {
1219 let mut builder = Builder::default();
1220 let string_elements: Vec<String> = vec![format!("{}{:?}",self.id,self.variants)];
1221 builder.push_record(string_elements);
1222 let mut table = builder.build();
1223 table.with(Style::modern_rounded());
1224 format!("{table}")
1225 }
1226
1227}
1228
1229impl Hash for MechEnum {
1230 fn hash<H: Hasher>(&self, state: &mut H) {
1231 self.id.hash(state);
1232 self.variants.hash(state);
1233 }
1234}