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      _ => 0,
291    }
292  }
293
294  pub fn pretty_print(&self) -> String {
295    let mut builder = Builder::default();
296    match self {
297      Value::U8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
298      Value::U16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
299      Value::U32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
300      Value::U64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
301      Value::U128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
302      Value::I8(x)   => {builder.push_record(vec![format!("{}",x.borrow())]);},
303      Value::I16(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
304      Value::I32(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
305      Value::I64(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
306      Value::I128(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
307      Value::F32(x)  => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
308      Value::F64(x)  => {builder.push_record(vec![format!("{}",x.borrow().0)]);},
309      Value::Bool(x) => {builder.push_record(vec![format!("{}",x.borrow())]);},
310      Value::Index(x)  => {builder.push_record(vec![format!("{}",x.borrow())]);},
311      Value::Atom(x) => {builder.push_record(vec![format!("{}",x)]);},
312      Value::Set(x)  => {return x.pretty_print();}
313      Value::Map(x)  => {return x.pretty_print();}
314      Value::String(x) => {builder.push_record(vec![format!("\"{}\"",x.borrow().clone())]);},
315      Value::Table(x)  => {return x.pretty_print();},
316      Value::Tuple(x)  => {return x.pretty_print();},
317      Value::Record(x) => {return x.pretty_print();},
318      Value::Enum(x) => {return x.pretty_print();},
319      Value::MatrixIndex(x) => {return x.pretty_print();}
320      Value::MatrixBool(x) => {return x.pretty_print();}
321      Value::MatrixU8(x)   => {return x.pretty_print();},
322      Value::MatrixU16(x)  => {return x.pretty_print();},
323      Value::MatrixU32(x)  => {return x.pretty_print();},
324      Value::MatrixU64(x)  => {return x.pretty_print();},
325      Value::MatrixU128(x) => {return x.pretty_print();},
326      Value::MatrixI8(x)   => {return x.pretty_print();},
327      Value::MatrixI16(x)  => {return x.pretty_print();},
328      Value::MatrixI32(x)  => {return x.pretty_print();},
329      Value::MatrixI64(x)  => {return x.pretty_print();},
330      Value::MatrixI128(x) => {return x.pretty_print();},
331      Value::MatrixF32(x)  => {return x.pretty_print();},
332      Value::MatrixF64(x)  => {return x.pretty_print();},
333      Value::MatrixValue(x)  => {return x.pretty_print();},
334      Value::MatrixString(x)  => {return x.pretty_print();},
335      Value::MutableReference(x) => {return x.borrow().pretty_print();},
336      Value::Empty => builder.push_record(vec!["_"]),
337      Value::IndexAll => builder.push_record(vec![":"]),
338      Value::Id(x) => builder.push_record(vec![format!("{:?}",humanize(x))]),
339      Value::Kind(x) => builder.push_record(vec![format!("{:?}",x)]),
340    };
341    let value_style = Style::empty()
342      .top(' ')
343      .left(' ')
344      .right(' ')
345      .bottom(' ')
346      .vertical(' ')
347      .intersection_bottom(' ')
348      .corner_top_left(' ')
349      .corner_top_right(' ')
350      .corner_bottom_left(' ')
351      .corner_bottom_right(' ');
352    let mut table = builder.build();
353    table.with(value_style);
354    format!("{table}")
355  }
356
357  pub fn shape(&self) -> Vec<usize> {
358    match self {
359      Value::U8(x) => vec![1,1],
360      Value::U16(x) => vec![1,1],
361      Value::U32(x) => vec![1,1],
362      Value::U64(x) => vec![1,1],
363      Value::U128(x) => vec![1,1],
364      Value::I8(x) => vec![1,1],
365      Value::I16(x) => vec![1,1],
366      Value::I32(x) => vec![1,1],
367      Value::I64(x) => vec![1,1],
368      Value::I128(x) => vec![1,1],
369      Value::F32(x) => vec![1,1],
370      Value::F64(x) => vec![1,1],
371      Value::Index(x) => vec![1,1],
372      Value::String(x) => vec![1,1],
373      Value::Bool(x) => vec![1,1],
374      Value::Atom(x) => vec![1,1],
375      Value::MatrixIndex(x) => x.shape(),
376      Value::MatrixBool(x) => x.shape(),
377      Value::MatrixU8(x) => x.shape(),
378      Value::MatrixU16(x) => x.shape(),
379      Value::MatrixU32(x) => x.shape(),
380      Value::MatrixU64(x) => x.shape(),
381      Value::MatrixU128(x) => x.shape(),
382      Value::MatrixI8(x) => x.shape(),
383      Value::MatrixI16(x) => x.shape(),
384      Value::MatrixI32(x) => x.shape(),
385      Value::MatrixI64(x) => x.shape(),
386      Value::MatrixI128(x) => x.shape(),
387      Value::MatrixF32(x) => x.shape(),
388      Value::MatrixF64(x) => x.shape(),
389      Value::MatrixString(x) => x.shape(),
390      Value::MatrixValue(x) => x.shape(),
391      Value::Enum(x) => vec![1,1],
392      Value::Table(x) => x.shape(),
393      Value::Set(x) => vec![1,x.set.len()],
394      Value::Map(x) => vec![1,x.map.len()],
395      Value::Record(x) => x.shape(),
396      Value::Tuple(x) => vec![1,x.size()],
397      Value::MutableReference(x) => x.borrow().shape(),
398      Value::Empty => vec![0,0],
399      Value::IndexAll => vec![0,0],
400      Value::Kind(_) => vec![0,0],
401      Value::Id(x) => vec![0,0],
402    }
403  }
404
405  pub fn kind(&self) -> ValueKind {
406    match self {
407      Value::U8(_) => ValueKind::U8,
408      Value::U16(_) => ValueKind::U16,
409      Value::U32(_) => ValueKind::U32,
410      Value::U64(_) => ValueKind::U64,
411      Value::U128(_) => ValueKind::U128,
412      Value::I8(_) => ValueKind::I8,
413      Value::I16(_) => ValueKind::I16,
414      Value::I32(_) => ValueKind::I32,
415      Value::I64(_) => ValueKind::I64,
416      Value::I128(_) => ValueKind::I128,
417      Value::F32(_) => ValueKind::F32,
418      Value::F64(_) => ValueKind::F64,
419      Value::String(_) => ValueKind::String,
420      Value::Bool(_) => ValueKind::Bool,
421      Value::Atom(x) => ValueKind::Atom(*x),
422      Value::MatrixIndex(x) => ValueKind::Matrix(Box::new(ValueKind::Index),x.shape()),
423      Value::MatrixBool(x) => ValueKind::Matrix(Box::new(ValueKind::Bool),x.shape()),
424      Value::MatrixU8(x) => ValueKind::Matrix(Box::new(ValueKind::U8),x.shape()),
425      Value::MatrixU16(x) => ValueKind::Matrix(Box::new(ValueKind::U16),x.shape()),
426      Value::MatrixU32(x) => ValueKind::Matrix(Box::new(ValueKind::U32),x.shape()),
427      Value::MatrixU64(x) => ValueKind::Matrix(Box::new(ValueKind::U64),x.shape()),
428      Value::MatrixU128(x) => ValueKind::Matrix(Box::new(ValueKind::U128),x.shape()),
429      Value::MatrixI8(x) => ValueKind::Matrix(Box::new(ValueKind::I8),x.shape()),
430      Value::MatrixI16(x) => ValueKind::Matrix(Box::new(ValueKind::I16),x.shape()),
431      Value::MatrixI32(x) => ValueKind::Matrix(Box::new(ValueKind::I32),x.shape()),
432      Value::MatrixI64(x) => ValueKind::Matrix(Box::new(ValueKind::I64),x.shape()),
433      Value::MatrixI128(x) => ValueKind::Matrix(Box::new(ValueKind::U128,),x.shape()),
434      Value::MatrixF32(x) => ValueKind::Matrix(Box::new(ValueKind::F32),x.shape()),
435      Value::MatrixF64(x) => ValueKind::Matrix(Box::new(ValueKind::F64),x.shape()),
436      Value::MatrixString(x) => ValueKind::Matrix(Box::new(ValueKind::String),x.shape()),
437      Value::MatrixValue(x) => ValueKind::Matrix(Box::new(ValueKind::Any),x.shape()),
438      Value::Table(x) => x.kind(),
439      Value::Set(x) => x.kind(),
440      Value::Map(x) => x.kind(),
441      Value::Record(x) => x.kind(),
442      Value::Tuple(x) => x.kind(),
443      Value::Enum(x) => x.kind(),
444      Value::MutableReference(x) => ValueKind::Reference(Box::new(x.borrow().kind())),
445      Value::Empty => ValueKind::Empty,
446      Value::IndexAll => ValueKind::Empty,
447      Value::Id(x) => ValueKind::Id,
448      Value::Index(x) => ValueKind::Index,
449      Value::Kind(x) => x.clone(),
450    }
451  }
452
453  pub fn is_matrix(&self) -> bool {
454    match self {
455      Value::MatrixIndex(_) | Value::MatrixBool(_) | Value::MatrixU8(_) | 
456      Value::MatrixU16(_) | Value::MatrixU32(_) | Value::MatrixU64(_) | 
457      Value::MatrixU128(_) | Value::MatrixI8(_) | Value::MatrixI16(_) | 
458      Value::MatrixI32(_) | Value::MatrixI64(_) | Value::MatrixI128(_) | 
459      Value::MatrixF32(_) | Value::MatrixF64(_) | Value::MatrixString(_) |
460      Value::MatrixValue(_) => true,
461      _ => false,
462    }
463  }
464
465  pub fn is_scalar(&self) -> bool {
466    match self {
467      Value::U8(_) | Value::U16(_) | Value::U32(_) | 
468      Value::U64(_) | Value::U128(_) | Value::I8(_) | 
469      Value::I16(_) | Value::I32(_) | Value::I64(_) | 
470      Value::I128(_) | Value::F32(_) | Value::F64(_) | 
471      Value::Bool(_) | Value::String(_) | 
472      Value::Atom(_) | Value::Index(_) => true,
473      _ => false,
474    }
475  }
476
477  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 }}
478  
479  impl_as_type!(i8);
480  impl_as_type!(i16);
481  impl_as_type!(i32);
482  impl_as_type!(i64);
483  impl_as_type!(i128);
484  impl_as_type!(u8);
485  impl_as_type!(u16);
486  impl_as_type!(u32);
487  impl_as_type!(u64);
488  impl_as_type!(u128);
489
490  pub fn as_string(&self) -> Option<Ref<String>> {
491    match self {
492      Value::String(v) => Some(v.clone()),
493      Value::U8(v) => Some(new_ref(v.borrow().to_string())),
494      Value::U16(v) => Some(new_ref(v.borrow().to_string())),
495      Value::U32(v) => Some(new_ref(v.borrow().to_string())),
496      Value::U64(v) => Some(new_ref(v.borrow().to_string())),
497      Value::U128(v) => Some(new_ref(v.borrow().to_string())),
498      Value::I8(v) => Some(new_ref(v.borrow().to_string())),
499      Value::I16(v) => Some(new_ref(v.borrow().to_string())),
500      Value::I32(v) => Some(new_ref(v.borrow().to_string())),
501      Value::I64(v) => Some(new_ref(v.borrow().to_string())),
502      Value::I128(v) => Some(new_ref(v.borrow().to_string())),
503      Value::F32(v) => Some(new_ref(format!("{}", v.borrow().0))),
504      Value::F64(v) => Some(new_ref(format!("{}", v.borrow().0))),
505      Value::Bool(v) => Some(new_ref(format!("{}", v.borrow()))),
506      Value::MutableReference(val) => val.borrow().as_string(),
507      _ => None,
508    }
509  }
510
511  pub fn as_f32(&self) -> Option<Ref<F32>> {
512    match self {
513      Value::U8(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
514      Value::U16(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
515      Value::U32(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
516      Value::U64(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
517      Value::U128(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
518      Value::I8(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
519      Value::I16(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
520      Value::I32(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
521      Value::I64(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
522      Value::I128(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
523      Value::F32(v) => Some(new_ref(F32::new((*v.borrow()).0 as f32))),
524      Value::F64(v) => Some(new_ref(F32::new((*v.borrow()).0 as f32))),
525      Value::MutableReference(val) => val.borrow().as_f32(),
526      _ => None,
527    }
528  }
529
530  pub fn as_f64(&self) -> Option<Ref<F64>> {
531    match self {
532      Value::U8(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
533      Value::U16(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
534      Value::U32(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
535      Value::U64(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
536      Value::U128(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
537      Value::I8(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
538      Value::I16(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
539      Value::I32(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
540      Value::I64(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
541      Value::I128(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
542      Value::F64(v) => Some(new_ref(F64::new((*v.borrow()).0 as f64))),
543      Value::F64(v) => Some(new_ref(F64::new((*v.borrow()).0 as f64))),
544      Value::MutableReference(val) => val.borrow().as_f64(),
545      _ => None,
546    }
547  }
548
549  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 }}
550  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 { None }}
551  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 { None }}
552
553  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 { None }}
554  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 { None }}
555  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 { None }}
556  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 { None }}
557  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 { None }}
558
559  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 { None }}
560  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 { None }}
561  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 { None }}
562  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 { None }}
563  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 { None }}
564
565  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 }}
566
567
568  pub fn as_vecusize(&self) -> Option<Vec<usize>> {
569    match self {
570      Value::MatrixIndex(v) => Some(v.as_vec()),
571      Value::MatrixI64(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
572      Value::MatrixF64(v) => Some(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
573      Value::MutableReference(x) => x.borrow().as_vecusize(),
574      Value::MatrixBool(_) => None,
575      Value::Bool(_) => None,
576      _ => todo!(),
577    }
578  }
579
580  pub fn as_index(&self) -> MResult<Value> {
581    match self.as_usize() {      
582      Some(ix) => Ok(Value::Index(new_ref(ix))),
583      None => match self.as_vecusize() {
584        Some(x) => {
585          let shape = self.shape();
586          let out = Value::MatrixIndex(usize::to_matrix(x, shape[0] * shape[1],1 ));
587          Ok(out)
588        },
589        None => match self.as_vecbool() {
590          Some(x) => {
591            let shape = self.shape();
592            let out = match (shape[0], shape[1]) {
593              (1,1) => Value::Bool(new_ref(x[0])),
594              (1,n) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
595              (m,1) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
596              (m,n) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
597            };
598            Ok(out)
599          }
600          None => match self.as_bool() {
601            Some(x) => Ok(Value::Bool(x)),
602            None => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledIndexKind}),
603          }
604        }
605      }
606    }
607  }
608
609  pub fn as_usize(&self) -> Option<usize> {
610    match self {      
611      Value::Index(v) => Some(*v.borrow()),
612      Value::U8(v) => Some(*v.borrow() as usize),
613      Value::U16(v) => Some(*v.borrow() as usize),
614      Value::U32(v) => Some(*v.borrow() as usize),
615      Value::U64(v) => Some(*v.borrow() as usize),
616      Value::U128(v) => Some(*v.borrow() as usize),
617      Value::I8(v) => Some(*v.borrow() as usize),
618      Value::I16(v) => Some(*v.borrow() as usize),
619      Value::I32(v) => Some(*v.borrow() as usize),
620      Value::I64(v) => Some(*v.borrow() as usize),
621      Value::I128(v) => Some(*v.borrow() as usize),
622      Value::F32(v) => Some((*v.borrow()).0 as usize),
623      Value::F64(v) => Some((*v.borrow()).0 as usize),
624      Value::Id(v) => Some(*v as usize),
625      Value::MutableReference(v) => v.borrow().as_usize(),
626      _ => None,
627    }
628  }
629
630}
631
632pub trait ToIndex {
633  fn to_index(&self) -> Value;
634}
635
636impl ToIndex for Ref<Vec<i64>> { fn to_index(&self) -> Value { (*self.borrow()).iter().map(|x| *x as usize).collect::<Vec<usize>>().to_value() } }
637
638pub trait ToValue {
639  fn to_value(&self) -> Value;
640}
641
642impl ToValue for Vec<usize> {
643  fn to_value(&self) -> Value {
644    match self.len() {
645      1 => Value::Index(new_ref(self[0].clone())),
646      //2 => Value::MatrixIndex(Matrix::RowVector2(new_ref(RowVector2::from_vec(self.clone())))),
647      //3 => Value::MatrixIndex(Matrix::RowVector3(new_ref(RowVector3::from_vec(self.clone())))),
648      //4 => Value::MatrixIndex(Matrix::RowVector4(new_ref(RowVector4::from_vec(self.clone())))),
649      n => Value::MatrixIndex(Matrix::DVector(new_ref(DVector::from_vec(self.clone())))),
650    }
651  }
652}
653
654impl ToValue for Ref<usize> { fn to_value(&self) -> Value { Value::Index(self.clone()) } }
655impl ToValue for Ref<u8>    { fn to_value(&self) -> Value { Value::U8(self.clone())    } }
656impl ToValue for Ref<u16>   { fn to_value(&self) -> Value { Value::U16(self.clone())   } }
657impl ToValue for Ref<u32>   { fn to_value(&self) -> Value { Value::U32(self.clone())   } }
658impl ToValue for Ref<u64>   { fn to_value(&self) -> Value { Value::U64(self.clone())   } }
659impl ToValue for Ref<u128>  { fn to_value(&self) -> Value { Value::U128(self.clone())  } }
660impl ToValue for Ref<i8>    { fn to_value(&self) -> Value { Value::I8(self.clone())    } }
661impl ToValue for Ref<i16>   { fn to_value(&self) -> Value { Value::I16(self.clone())   } }
662impl ToValue for Ref<i32>   { fn to_value(&self) -> Value { Value::I32(self.clone())   } }
663impl ToValue for Ref<i64>   { fn to_value(&self) -> Value { Value::I64(self.clone())   } }
664impl ToValue for Ref<i128>  { fn to_value(&self) -> Value { Value::I128(self.clone())  } }
665impl ToValue for Ref<F32>   { fn to_value(&self) -> Value { Value::F32(self.clone())   } }
666impl ToValue for Ref<F64>   { fn to_value(&self) -> Value { Value::F64(self.clone())   } }
667impl ToValue for Ref<bool>  { fn to_value(&self) -> Value { Value::Bool(self.clone())  } }
668impl ToValue for Ref<String>  { fn to_value(&self) -> Value { Value::String(self.clone())  } }
669
670macro_rules! to_value_matrix {
671  ($($nd_matrix_kind:ident, $matrix_kind:ident, $base_type:ty),+ $(,)?) => {
672    $(
673      impl ToValue for Ref<$nd_matrix_kind<$base_type>> {
674        fn to_value(&self) -> Value {
675          Value::$matrix_kind(Matrix::<$base_type>::$nd_matrix_kind(self.clone()))
676        }
677      }
678    )+
679  };}
680
681macro_rules! impl_to_value_matrix {
682  ($matrix_kind:ident) => {
683    to_value_matrix!(
684      $matrix_kind, MatrixIndex,  usize,
685      $matrix_kind, MatrixBool,   bool,
686      $matrix_kind, MatrixI8,     i8,
687      $matrix_kind, MatrixI16,    i16,
688      $matrix_kind, MatrixI32,    i32,
689      $matrix_kind, MatrixI64,    i64,
690      $matrix_kind, MatrixI128,   i128,
691      $matrix_kind, MatrixU8,     u8,
692      $matrix_kind, MatrixU16,    u16,
693      $matrix_kind, MatrixU32,    u32,
694      $matrix_kind, MatrixU64,    u64,
695      $matrix_kind, MatrixU128,   u128,
696      $matrix_kind, MatrixF32,    F32,
697      $matrix_kind, MatrixF64,    F64,
698      $matrix_kind, MatrixString, String,
699    );
700  }
701}
702
703impl_to_value_matrix!(Matrix2x3);
704impl_to_value_matrix!(Matrix3x2);
705impl_to_value_matrix!(Matrix1);
706impl_to_value_matrix!(Matrix2);
707impl_to_value_matrix!(Matrix3);
708impl_to_value_matrix!(Matrix4);
709impl_to_value_matrix!(Vector2);
710impl_to_value_matrix!(Vector3);
711impl_to_value_matrix!(Vector4);
712impl_to_value_matrix!(RowVector2);
713impl_to_value_matrix!(RowVector3);
714impl_to_value_matrix!(RowVector4);
715impl_to_value_matrix!(RowDVector);
716impl_to_value_matrix!(DVector);
717impl_to_value_matrix!(DMatrix);
718
719// Set --------------------------------------------------------------------------
720
721#[derive(Clone, Debug, PartialEq, Eq)]
722pub struct MechSet {
723  pub kind: ValueKind,
724  pub num_elements: usize,
725  pub set: IndexSet<Value>,
726}
727
728impl MechSet {
729
730  pub fn kind(&self) -> ValueKind {
731    ValueKind::Set(Box::new(self.kind.clone()), self.num_elements)
732  }
733
734  pub fn from_vec(vec: Vec<Value>) -> MechSet {
735    let mut set = IndexSet::new();
736    for v in vec {
737      set.insert(v);
738    }
739    let kind = if set.len() > 0 { set.iter().next().unwrap().kind() } else { ValueKind::Empty };
740    MechSet{
741      kind,
742      num_elements: set.len(),
743      set}
744  }
745
746  pub fn pretty_print(&self) -> String {
747    let mut builder = Builder::default();
748    let mut element_strings = vec![];
749    for x in self.set.iter() {
750      element_strings.push(x.pretty_print());
751    }
752    builder.push_record(element_strings);
753    let mut table = builder.build();
754    table.with(Style::modern_rounded());
755    format!("{table}")
756  }
757
758}
759
760impl Hash for MechSet {
761  fn hash<H: Hasher>(&self, state: &mut H) {
762    for x in self.set.iter() {
763      x.hash(state)
764    }
765  }
766}
767
768// Map ------------------------------------------------------------------
769
770#[derive(Clone, Debug, PartialEq, Eq)]
771pub struct MechMap {
772  pub key_kind: ValueKind,
773  pub value_kind: ValueKind,
774  pub num_elements: usize,
775  pub map: IndexMap<Value,Value>,
776}
777
778impl MechMap {
779
780  pub fn kind(&self) -> ValueKind {
781    ValueKind::Map(Box::new(self.key_kind.clone()), Box::new(self.value_kind.clone()))
782  }
783
784  pub fn pretty_print(&self) -> String {
785    let mut builder = Builder::default();
786    let mut element_strings = vec![];
787    let mut key_strings = vec![];
788    for (k,v) in self.map.iter() {
789      element_strings.push(v.pretty_print());
790      key_strings.push(k.pretty_print());
791    }    
792    builder.push_record(key_strings);
793    builder.push_record(element_strings);
794    let mut table = builder.build();
795    table.with(Style::modern_rounded());
796    format!("{table}")
797  }
798
799  pub fn from_vec(vec: Vec<(Value,Value)>) -> MechMap {
800    let mut map = IndexMap::new();
801    for (k,v) in vec {
802      map.insert(k,v);
803    }
804    MechMap{
805      key_kind: map.keys().next().unwrap().kind(),
806      value_kind: map.values().next().unwrap().kind(),
807      num_elements: map.len(),
808      map}
809  }
810}
811
812impl Hash for MechMap {
813  fn hash<H: Hasher>(&self, state: &mut H) {
814    for x in self.map.iter() {
815      x.hash(state)
816    }
817  }
818}
819
820// Table ------------------------------------------------------------------
821
822#[derive(Clone, Debug, PartialEq, Eq)]
823pub struct MechTable {
824  rows: usize,
825  cols: usize,
826  data: IndexMap<Value,(ValueKind,Matrix<Value>)>,
827  col_names: HashMap<Value,String>,
828}
829
830impl MechTable {
831
832  pub fn new(rows: usize, cols: usize, data: IndexMap<Value,(ValueKind,Matrix<Value>)>, col_names: HashMap<Value,String>) -> MechTable {
833    MechTable{rows, cols, data, col_names}
834  }
835
836  pub fn kind(&self) -> ValueKind {
837    ValueKind::Table(
838      self.data.iter().map(|(_,v)| v.0.clone()).collect(),
839      self.rows)
840  }
841
842  pub fn rows(&self) -> usize {
843    self.rows
844  }
845
846  pub fn cols(&self) -> usize {
847    self.cols
848  }
849
850  pub fn get(&self, key: &Value) -> Option<&(ValueKind,Matrix<Value>)> {
851    self.data.get(key)
852  }
853
854  pub fn pretty_print(&self) -> String {
855    let mut builder = Builder::default();
856    for (k,(knd,val)) in &self.data {
857      let name = self.col_names.get(k).unwrap();
858      let mut col_string = vec![format!("{}<{}>", name.to_string(), knd), val.pretty_print()];
859      builder.push_column(col_string);
860    }
861    let mut table = builder.build();
862    table.with(Style::modern_rounded());
863    format!("{table}")
864  }
865
866  pub fn shape(&self) -> Vec<usize> {
867    vec![self.rows,self.cols]
868  }
869}
870
871impl Hash for MechTable {
872  fn hash<H: Hasher>(&self, state: &mut H) {
873    for (k,(knd,val)) in self.data.iter() {
874      k.hash(state);
875      knd.hash(state);
876      val.hash(state);
877    }
878  }
879}
880
881// Record ------------------------------------------------------------------
882
883#[derive(Clone, Debug, PartialEq, Eq)]
884pub struct MechRecord {
885  pub cols: usize,
886  pub kinds: Vec<ValueKind>,
887  pub data: IndexMap<u64,Value>,
888}
889
890impl MechRecord {
891
892  pub fn get(&self, key: &u64) -> Option<&Value> {
893    self.data.get(key)
894  }
895
896  pub fn from_vec(vec: Vec<(u64,Value)>) -> MechRecord {
897    let mut data = IndexMap::new();
898    for (k,v) in vec {
899      data.insert(k,v);
900    }
901    let kinds = data.iter().map(|(_,v)| v.kind()).collect();
902    MechRecord{cols: data.len(), kinds, data}
903  }
904
905  pub fn insert_field(&mut self, key: u64, value: Value) {
906    self.cols += 1;
907    self.kinds.push(value.kind());
908    self.data.insert(key, value);
909  }
910
911  pub fn kind(&self) -> ValueKind {
912    ValueKind::Record(self.kinds.clone())
913  }
914
915  pub fn pretty_print(&self) -> String {
916    let mut builder = Builder::default();
917    let mut key_strings = vec![];
918    let mut element_strings = vec![];
919    for (k,v) in &self.data {
920      key_strings.push(format!("{:?}",humanize(k)));
921      element_strings.push(v.pretty_print());
922    }
923    builder.push_record(key_strings);
924    builder.push_record(element_strings);
925    let mut table = builder.build();
926    table.with(Style::modern_rounded());
927    format!("{table}")
928  }
929
930  pub fn shape(&self) -> Vec<usize> {
931    vec![1,self.cols]
932  }
933}
934
935impl Hash for MechRecord {
936  fn hash<H: Hasher>(&self, state: &mut H) {
937    for (k,v) in self.data.iter() {
938      k.hash(state);
939      v.hash(state);
940    }
941  }
942}
943
944// Tuple ----------------------------------------------------------------------
945
946#[derive(Clone, Debug, PartialEq, Eq)]
947pub struct MechTuple {
948  pub elements: Vec<Box<Value>>
949}
950
951impl MechTuple {
952
953  pub fn pretty_print(&self) -> String {
954    let mut builder = Builder::default();
955    let string_elements: Vec<String> = self.elements.iter().map(|e| e.pretty_print()).collect::<Vec<String>>();
956    builder.push_record(string_elements);
957    let mut table = builder.build();
958    table.with(Style::modern_rounded());
959    format!("{table}")
960  }
961
962  pub fn from_vec(elements: Vec<Value>) -> Self {
963    MechTuple{elements: elements.iter().map(|m| Box::new(m.clone())).collect::<Vec<Box<Value>>>()}
964  }
965
966  pub fn size(&self) -> usize {
967    self.elements.len()
968  }
969
970  pub fn kind(&self) -> ValueKind {
971    ValueKind::Tuple(self.elements.iter().map(|x| x.kind()).collect())
972  }
973
974}
975
976impl Hash for MechTuple {
977  fn hash<H: Hasher>(&self, state: &mut H) {
978    for x in self.elements.iter() {
979        x.hash(state)
980    }
981  }
982}
983
984// Enum -----------------------------------------------------------------------
985
986#[derive(Clone, Debug, PartialEq, Eq)]
987pub struct MechEnum {
988  pub id: u64,
989  pub variants: Vec<(u64, Option<Value>)>,
990}
991
992impl MechEnum {
993
994  pub fn kind(&self) -> ValueKind {
995    ValueKind::Enum(self.id)
996  }
997
998  pub fn pretty_print(&self) -> String {
999    let mut builder = Builder::default();
1000    let string_elements: Vec<String> = vec![format!("{}{:?}",self.id,self.variants)];
1001    builder.push_record(string_elements);
1002    let mut table = builder.build();
1003    table.with(Style::modern_rounded());
1004    format!("{table}")
1005  }
1006
1007}
1008
1009impl Hash for MechEnum {
1010  fn hash<H: Hasher>(&self, state: &mut H) {
1011    self.id.hash(state);
1012    self.variants.hash(state);
1013  }
1014}