mech_core/
value.rs

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// Value ----------------------------------------------------------------------
49
50#[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, // Kind is not a value, so it has no size
302      Value::Empty => 0,
303      Value::IndexAll => 0, // IndexAll is a special value, so it has no size
304    }
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      //2 => Value::MatrixIndex(Matrix::RowVector2(new_ref(RowVector2::from_vec(self.clone())))),
708      //3 => Value::MatrixIndex(Matrix::RowVector3(new_ref(RowVector3::from_vec(self.clone())))),
709      //4 => Value::MatrixIndex(Matrix::RowVector4(new_ref(RowVector4::from_vec(self.clone())))),
710      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// Set --------------------------------------------------------------------------
781
782#[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// Map ------------------------------------------------------------------
859
860#[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// Table ------------------------------------------------------------------
929
930#[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    // Start table
944    table.push_str("<table class=\"mech-table\">");
945
946    // Header
947    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    // Body
955    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// Record ------------------------------------------------------------------
1028
1029#[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// Tuple ----------------------------------------------------------------------
1126
1127#[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// Enum -----------------------------------------------------------------------
1189
1190#[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}