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 std::fmt::Display for ValueKind {
58  fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
59    match self {
60      ValueKind::U8 => write!(f, "u8"),
61      ValueKind::U16 => write!(f, "u16"),
62      ValueKind::U32 => write!(f, "u32"),
63      ValueKind::U64 => write!(f, "u64"),
64      ValueKind::U128 => write!(f, "u128"),
65      ValueKind::I8 => write!(f, "i8"),
66      ValueKind::I16 => write!(f, "i16"),
67      ValueKind::I32 => write!(f, "i32"),
68      ValueKind::I64 => write!(f, "i64"),
69      ValueKind::I128 => write!(f, "i128"),
70      ValueKind::F32 => write!(f, "f32"),
71      ValueKind::F64 => write!(f, "f64"),
72      ValueKind::String => write!(f, "string"),
73      ValueKind::Bool => write!(f, "bool"),
74      ValueKind::Matrix(x,s) => write!(f, "[{:?}]:{:?},{:?}",x,s[0],s[1]),
75      ValueKind::Enum(x) => write!(f, "{:?}",x),
76      ValueKind::Set(x,el) => write!(f, "{{{:?}}}:{}", x, el),
77      ValueKind::Map(x,y) => write!(f, "{{{:?}:{:?}}}",x,y),
78      ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
79      ValueKind::Table(x,y) => write!(f, "{{{}}}:{}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(","),y),
80      ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
81      ValueKind::Id => write!(f, "id"),
82      ValueKind::Index => write!(f, "ix"),
83      ValueKind::Reference(x) => write!(f, "{:?}",x),
84      ValueKind::Atom(x) => write!(f, "`{:?}",x),
85      ValueKind::Empty => write!(f, "_"),
86      ValueKind::Any => write!(f, "_"),
87    }
88  }
89}
90
91
92impl fmt::Debug for ValueKind {
93  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94    match self {
95      ValueKind::U8 => write!(f, "u8"),
96      ValueKind::U16 => write!(f, "u16"),
97      ValueKind::U32 => write!(f, "u32"),
98      ValueKind::U64 => write!(f, "u64"),
99      ValueKind::U128 => write!(f, "u128"),
100      ValueKind::I8 => write!(f, "i8"),
101      ValueKind::I16 => write!(f, "i16"),
102      ValueKind::I32 => write!(f, "i32"),
103      ValueKind::I64 => write!(f, "i64"),
104      ValueKind::I128 => write!(f, "i128"),
105      ValueKind::F32 => write!(f, "f32"),
106      ValueKind::F64 => write!(f, "f64"),
107      ValueKind::String => write!(f, "string"),
108      ValueKind::Bool => write!(f, "bool"),
109      ValueKind::Matrix(x,s) => write!(f, "[{:?}]:{:?},{:?}",x,s[0],s[1]),
110      ValueKind::Enum(x) => write!(f, "{:?}",x),
111      ValueKind::Set(x,el) => write!(f, "{{{:?}}}:{}", x, el),
112      ValueKind::Map(x,y) => write!(f, "{{{:?}:{:?}}}",x,y),
113      ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
114      ValueKind::Table(x,y) => write!(f, "{{{}}}:{}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(","),y),
115      ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
116      ValueKind::Id => write!(f, "id"),
117      ValueKind::Index => write!(f, "ix"),
118      ValueKind::Reference(x) => write!(f, "{:?}",x),
119      ValueKind::Atom(x) => write!(f, "`{:?}",x),
120      ValueKind::Empty => write!(f, "_"),
121      ValueKind::Any => write!(f, "_"),
122    }
123  }
124}
125
126impl ValueKind {
127  pub fn is_compatible(k1: ValueKind, k2: ValueKind) -> bool {
128    match k1 {
129      ValueKind::Reference(x) => {
130        ValueKind::is_compatible(*x,k2)
131      }
132      ValueKind::Matrix(x,_) => {
133        *x == k2
134      }
135      x => x == k2,
136    }
137  }
138}
139
140#[derive(Clone, Debug, PartialEq, Eq)]
141pub enum Value {
142  U8(Ref<u8>),
143  U16(Ref<u16>),
144  U32(Ref<u32>),
145  U64(Ref<u64>),
146  U128(Ref<u128>),
147  I8(Ref<i8>),
148  I16(Ref<i16>),
149  I32(Ref<i32>),
150  I64(Ref<i64>),
151  I128(Ref<i128>),
152  F32(Ref<F32>),
153  F64(Ref<F64>),
154  String(String),
155  Bool(Ref<bool>),
156  Atom(u64),
157  MatrixIndex(Matrix<usize>),
158  MatrixBool(Matrix<bool>),
159  MatrixU8(Matrix<u8>),
160  MatrixU16(Matrix<u16>),
161  MatrixU32(Matrix<u32>),
162  MatrixU64(Matrix<u64>),
163  MatrixU128(Matrix<u128>),
164  MatrixI8(Matrix<i8>),
165  MatrixI16(Matrix<i16>),
166  MatrixI32(Matrix<i32>),
167  MatrixI64(Matrix<i64>),
168  MatrixI128(Matrix<i128>),
169  MatrixF32(Matrix<F32>),
170  MatrixF64(Matrix<F64>),
171  MatrixValue(Matrix<Value>),
172  Set(MechSet),
173  Map(MechMap),
174  Record(MechRecord),
175  Table(MechTable),
176  Tuple(MechTuple),
177  Enum(Box<MechEnum>),
178  Id(u64),
179  Index(Ref<usize>),
180  MutableReference(MutableReference),
181  Kind(ValueKind),
182  IndexAll,
183  Empty
184}
185
186impl fmt::Display for Value {
187  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
188    self.pretty_print().fmt(f)
189  }
190}
191
192impl Hash for Value {
193  fn hash<H: Hasher>(&self, state: &mut H) {
194    match self {
195      Value::Id(x)   => x.hash(state),
196      Value::Kind(x) => x.hash(state),
197      Value::U8(x)   => x.borrow().hash(state),
198      Value::U16(x)  => x.borrow().hash(state),
199      Value::U32(x)  => x.borrow().hash(state),
200      Value::U64(x)  => x.borrow().hash(state),
201      Value::U128(x) => x.borrow().hash(state),
202      Value::I8(x)   => x.borrow().hash(state),
203      Value::I16(x)  => x.borrow().hash(state),
204      Value::I32(x)  => x.borrow().hash(state),
205      Value::I64(x)  => x.borrow().hash(state),
206      Value::I128(x) => x.borrow().hash(state),
207      Value::F32(x)  => x.borrow().hash(state),
208      Value::F64(x)  => x.borrow().hash(state),
209      Value::Index(x)=> x.borrow().hash(state),
210      Value::Bool(x) => x.borrow().hash(state),
211      Value::Atom(x) => x.hash(state),
212      Value::Set(x)  => x.hash(state),
213      Value::Map(x)  => x.hash(state),
214      Value::Table(x) => x.hash(state),
215      Value::Tuple(x) => x.hash(state),
216      Value::Record(x) => x.hash(state),
217      Value::Enum(x) => x.hash(state),
218      Value::String(x) => x.hash(state),
219      Value::MatrixBool(x) => x.hash(state),
220      Value::MatrixIndex(x) => x.hash(state),
221      Value::MatrixU8(x)   => x.hash(state),
222      Value::MatrixU16(x)  => x.hash(state),
223      Value::MatrixU32(x)  => x.hash(state),
224      Value::MatrixU64(x)  => x.hash(state),
225      Value::MatrixU128(x) => x.hash(state),
226      Value::MatrixI8(x)   => x.hash(state),
227      Value::MatrixI16(x)  => x.hash(state),
228      Value::MatrixI32(x)  => x.hash(state),
229      Value::MatrixI64(x)  => x.hash(state),
230      Value::MatrixI128(x) => x.hash(state),
231      Value::MatrixF32(x)  => x.hash(state),
232      Value::MatrixF64(x)  => x.hash(state),
233      Value::MatrixValue(x)  => x.hash(state),
234      Value::MutableReference(x) => x.borrow().hash(state),
235      Value::Empty => Value::Empty.hash(state),
236      Value::IndexAll => Value::IndexAll.hash(state),
237    }
238  }
239}
240
241impl Value {
242
243  pub fn size_of(&self) -> usize {
244    match self {
245      Value::U8(x) => 1,
246      Value::U16(x) => 2,
247      Value::U32(x) => 4,
248      Value::U64(x) => 8,
249      Value::U128(x) => 16,
250      Value::I8(x) => 1,
251      Value::I16(x) => 2,
252      Value::I32(x) => 4,
253      Value::I64(x) => 8,
254      Value::I128(x) => 16,
255      Value::F32(x) => 4,
256      Value::F64(x) => 8,
257      Value::Bool(x) => 1,
258      Value::MatrixIndex(x) =>x.size_of(),
259      Value::MatrixBool(x) =>x.size_of(),
260      Value::MatrixU8(x)   => x.size_of(),
261      Value::MatrixU16(x)  => x.size_of(),
262      Value::MatrixU32(x)  => x.size_of(),
263      Value::MatrixU64(x)  => x.size_of(),
264      Value::MatrixU128(x) => x.size_of(),
265      Value::MatrixI8(x)   => x.size_of(),
266      Value::MatrixI16(x)  => x.size_of(),
267      Value::MatrixI32(x)  => x.size_of(),
268      Value::MatrixI64(x)  => x.size_of(),
269      Value::MatrixI128(x) => x.size_of(),
270      Value::MatrixF32(x)  => x.size_of(),
271      Value::MatrixF64(x)  => x.size_of(),
272      Value::MatrixValue(x)  => x.size_of(),
273      _ => 0,
274    }
275  }
276
277  pub fn pretty_print(&self) -> String {
278    let mut builder = Builder::default();
279    match self {
280      Value::U8(x)   => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
281      Value::U16(x)  => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
282      Value::U32(x)  => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
283      Value::U64(x)  => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
284      Value::U128(x) => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
285      Value::I8(x)   => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
286      Value::I16(x)  => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
287      Value::I32(x)  => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
288      Value::I64(x)  => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
289      Value::I128(x) => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
290      Value::F32(x)  => {builder.push_record(vec![format!("{:?}",x.borrow().0)]);},
291      Value::F64(x)  => {builder.push_record(vec![format!("{:?}",x.borrow().0)]);},
292      Value::Bool(x) => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
293      Value::Index(x)  => {builder.push_record(vec![format!("{:?}",x.borrow())]);},
294      Value::Atom(x) => {builder.push_record(vec![format!("{:?}",x)]);},
295      Value::Set(x)  => {return x.pretty_print();}
296      Value::Map(x)  => {return x.pretty_print();}
297      Value::String(x) => {builder.push_record(vec![x])},
298      Value::Table(x)  => {return x.pretty_print();},
299      Value::Tuple(x)  => {return x.pretty_print();},
300      Value::Record(x) => {return x.pretty_print();},
301      Value::Enum(x) => {return x.pretty_print();},
302      Value::MatrixIndex(x) => {return x.pretty_print();}
303      Value::MatrixBool(x) => {return x.pretty_print();}
304      Value::MatrixU8(x)   => {return x.pretty_print();},
305      Value::MatrixU16(x)  => {return x.pretty_print();},
306      Value::MatrixU32(x)  => {return x.pretty_print();},
307      Value::MatrixU64(x)  => {return x.pretty_print();},
308      Value::MatrixU128(x) => {return x.pretty_print();},
309      Value::MatrixI8(x)   => {return x.pretty_print();},
310      Value::MatrixI16(x)  => {return x.pretty_print();},
311      Value::MatrixI32(x)  => {return x.pretty_print();},
312      Value::MatrixI64(x)  => {return x.pretty_print();},
313      Value::MatrixI128(x) => {return x.pretty_print();},
314      Value::MatrixF32(x)  => {return x.pretty_print();},
315      Value::MatrixF64(x)  => {return x.pretty_print();},
316      Value::MatrixValue(x)  => {return x.pretty_print();},
317      Value::MutableReference(x) => {return x.borrow().pretty_print();},
318      Value::Empty => builder.push_record(vec!["_"]),
319      Value::IndexAll => builder.push_record(vec![":"]),
320      Value::Id(x) => builder.push_record(vec![format!("{:?}",humanize(x))]),
321      Value::Kind(x) => builder.push_record(vec![format!("{:?}",x)]),
322    };
323    let value_style = Style::empty()
324      .top(' ')
325      .left(' ')
326      .right(' ')
327      .bottom(' ')
328      .vertical(' ')
329      .intersection_bottom(' ')
330      .corner_top_left(' ')
331      .corner_top_right(' ')
332      .corner_bottom_left(' ')
333      .corner_bottom_right(' ');
334    let mut table = builder.build();
335    table.with(value_style);
336    format!("{table}")
337  }
338
339  pub fn shape(&self) -> Vec<usize> {
340    match self {
341      Value::U8(x) => vec![1,1],
342      Value::U16(x) => vec![1,1],
343      Value::U32(x) => vec![1,1],
344      Value::U64(x) => vec![1,1],
345      Value::U128(x) => vec![1,1],
346      Value::I8(x) => vec![1,1],
347      Value::I16(x) => vec![1,1],
348      Value::I32(x) => vec![1,1],
349      Value::I64(x) => vec![1,1],
350      Value::I128(x) => vec![1,1],
351      Value::F32(x) => vec![1,1],
352      Value::F64(x) => vec![1,1],
353      Value::Index(x) => vec![1,1],
354      Value::String(x) => vec![1,1],
355      Value::Bool(x) => vec![1,1],
356      Value::Atom(x) => vec![1,1],
357      Value::MatrixIndex(x) => x.shape(),
358      Value::MatrixBool(x) => x.shape(),
359      Value::MatrixU8(x) => x.shape(),
360      Value::MatrixU16(x) => x.shape(),
361      Value::MatrixU32(x) => x.shape(),
362      Value::MatrixU64(x) => x.shape(),
363      Value::MatrixU128(x) => x.shape(),
364      Value::MatrixI8(x) => x.shape(),
365      Value::MatrixI16(x) => x.shape(),
366      Value::MatrixI32(x) => x.shape(),
367      Value::MatrixI64(x) => x.shape(),
368      Value::MatrixI128(x) => x.shape(),
369      Value::MatrixF32(x) => x.shape(),
370      Value::MatrixF64(x) => x.shape(),
371      Value::MatrixValue(x) => x.shape(),
372      Value::Enum(x) => vec![1,1],
373      Value::Table(x) => x.shape(),
374      Value::Set(x) => vec![1,x.set.len()],
375      Value::Map(x) => vec![1,x.map.len()],
376      Value::Record(x) => x.shape(),
377      Value::Tuple(x) => vec![1,x.size()],
378      Value::MutableReference(x) => x.borrow().shape(),
379      Value::Empty => vec![0,0],
380      Value::IndexAll => vec![0,0],
381      Value::Kind(_) => vec![0,0],
382      Value::Id(x) => vec![0,0],
383    }
384  }
385
386  pub fn kind(&self) -> ValueKind {
387    match self {
388      Value::U8(_) => ValueKind::U8,
389      Value::U16(_) => ValueKind::U16,
390      Value::U32(_) => ValueKind::U32,
391      Value::U64(_) => ValueKind::U64,
392      Value::U128(_) => ValueKind::U128,
393      Value::I8(_) => ValueKind::I8,
394      Value::I16(_) => ValueKind::I16,
395      Value::I32(_) => ValueKind::I32,
396      Value::I64(_) => ValueKind::I64,
397      Value::I128(_) => ValueKind::I128,
398      Value::F32(_) => ValueKind::F32,
399      Value::F64(_) => ValueKind::F64,
400      Value::String(_) => ValueKind::String,
401      Value::Bool(_) => ValueKind::Bool,
402      Value::Atom(x) => ValueKind::Atom(*x),
403      Value::MatrixIndex(x) => ValueKind::Matrix(Box::new(ValueKind::Index),x.shape()),
404      Value::MatrixBool(x) => ValueKind::Matrix(Box::new(ValueKind::Bool),x.shape()),
405      Value::MatrixU8(x) => ValueKind::Matrix(Box::new(ValueKind::U8),x.shape()),
406      Value::MatrixU16(x) => ValueKind::Matrix(Box::new(ValueKind::U16),x.shape()),
407      Value::MatrixU32(x) => ValueKind::Matrix(Box::new(ValueKind::U32),x.shape()),
408      Value::MatrixU64(x) => ValueKind::Matrix(Box::new(ValueKind::U64),x.shape()),
409      Value::MatrixU128(x) => ValueKind::Matrix(Box::new(ValueKind::U128),x.shape()),
410      Value::MatrixI8(x) => ValueKind::Matrix(Box::new(ValueKind::I8),x.shape()),
411      Value::MatrixI16(x) => ValueKind::Matrix(Box::new(ValueKind::I16),x.shape()),
412      Value::MatrixI32(x) => ValueKind::Matrix(Box::new(ValueKind::I32),x.shape()),
413      Value::MatrixI64(x) => ValueKind::Matrix(Box::new(ValueKind::I64),x.shape()),
414      Value::MatrixI128(x) => ValueKind::Matrix(Box::new(ValueKind::U128,),x.shape()),
415      Value::MatrixF32(x) => ValueKind::Matrix(Box::new(ValueKind::F32),x.shape()),
416      Value::MatrixF64(x) => ValueKind::Matrix(Box::new(ValueKind::F64),x.shape()),
417      Value::MatrixValue(x) => ValueKind::Matrix(Box::new(ValueKind::Any),x.shape()),
418      Value::Table(x) => x.kind(),
419      Value::Set(x) => x.kind(),
420      Value::Map(x) => x.kind(),
421      Value::Record(x) => x.kind(),
422      Value::Tuple(x) => x.kind(),
423      Value::Enum(x) => x.kind(),
424      Value::MutableReference(x) => ValueKind::Reference(Box::new(x.borrow().kind())),
425      Value::Empty => ValueKind::Empty,
426      Value::IndexAll => ValueKind::Empty,
427      Value::Id(x) => ValueKind::Id,
428      Value::Index(x) => ValueKind::Index,
429      Value::Kind(x) => x.clone(),
430    }
431  }
432
433  pub fn is_scalar(&self) -> bool {
434    match self {
435      Value::U8(_)  | Value::U16(_) | Value::U32(_) | Value::U64(_) | Value::U128(_) | 
436      Value::I8(_)  | Value::I16(_) | Value::I32(_) | Value::I64(_) | Value::I128(_) | 
437      Value::F32(_) | Value::F64(_) | Value::String(_)  | Value::Bool(_) | Value::Atom(_) => true,
438      _ => todo!(), 
439      /*Value::MatrixIndex(x) => ValueKind::Matrix(Box::new(ValueKind::Index),(x.shape()[0],x.shape()[1])),
440      Value::MatrixBool(x) => ValueKind::Matrix(Box::new(ValueKind::Bool),(x.shape()[0],x.shape()[1])),
441      Value::MatrixU8(x) => ValueKind::Matrix(Box::new(ValueKind::U8),(x.shape()[0],x.shape()[1])),
442      Value::MatrixU16(x) => ValueKind::Matrix(Box::new(ValueKind::U16),(x.shape()[0],x.shape()[1])),
443      Value::MatrixU32(x) => ValueKind::Matrix(Box::new(ValueKind::U32),(x.shape()[0],x.shape()[1])),
444      Value::MatrixU64(x) => ValueKind::Matrix(Box::new(ValueKind::U64),(x.shape()[0],x.shape()[1])),
445      Value::MatrixU128(x) => ValueKind::Matrix(Box::new(ValueKind::U128),(x.shape()[0],x.shape()[1])),
446      Value::MatrixI8(x) => ValueKind::Matrix(Box::new(ValueKind::I8),(x.shape()[0],x.shape()[1])),
447      Value::MatrixI16(x) => ValueKind::Matrix(Box::new(ValueKind::I16),(x.shape()[0],x.shape()[1])),
448      Value::MatrixI32(x) => ValueKind::Matrix(Box::new(ValueKind::I32),(x.shape()[0],x.shape()[1])),
449      Value::MatrixI64(x) => ValueKind::Matrix(Box::new(ValueKind::I64),(x.shape()[0],x.shape()[1])),
450      Value::MatrixI128(x) => ValueKind::Matrix(Box::new(ValueKind::U128,),(x.shape()[0],x.shape()[1])),
451      Value::MatrixF32(x) => ValueKind::Matrix(Box::new(ValueKind::F32),(x.shape()[0],x.shape()[1])),
452      Value::MatrixF64(x) => ValueKind::Matrix(Box::new(ValueKind::F64),(x.shape()[0],x.shape()[1])),
453      Value::MatrixValue(x) => ValueKind::Matrix(Box::new(ValueKind::Any),(x.shape()[0],x.shape()[1])),
454      Value::Table(x) => ValueKind::Table,
455      Value::Set(x) => ValueKind::Set,
456      Value::Map(x) => ValueKind::Map,
457      Value::Record(x) => ValueKind::Record,
458      Value::Tuple(x) => ValueKind::Tuple,
459      Value::Enum(x) => ValueKind::Enum(x.id),
460      Value::MutableReference(x) => ValueKind::Reference,
461      Value::Empty => ValueKind::Empty,
462      Value::IndexAll => ValueKind::Empty,
463      Value::Id(x) => ValueKind::Id,
464      Value::Index(x) => ValueKind::Index,
465      Value::Kind(x) => x.clone(),*/
466    }
467  }
468
469  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 }}
470  
471  impl_as_type!(i8);
472  impl_as_type!(i16);
473  impl_as_type!(i32);
474  impl_as_type!(i64);
475  impl_as_type!(i128);
476  impl_as_type!(u8);
477  impl_as_type!(u16);
478  impl_as_type!(u32);
479  impl_as_type!(u64);
480  impl_as_type!(u128);
481
482  pub fn as_f32(&self) -> Option<Ref<F32>> {
483    match self {
484      Value::U8(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
485      Value::U16(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
486      Value::U32(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
487      Value::U64(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
488      Value::U128(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
489      Value::I8(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
490      Value::I16(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
491      Value::I32(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
492      Value::I64(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
493      Value::I128(v) => Some(new_ref(F32::new(*v.borrow() as f32))),
494      Value::F32(v) => Some(new_ref(F32::new((*v.borrow()).0 as f32))),
495      Value::F64(v) => Some(new_ref(F32::new((*v.borrow()).0 as f32))),
496      Value::MutableReference(val) => val.borrow().as_f32(),
497      _ => None,
498    }
499  }
500
501  pub fn as_f64(&self) -> Option<Ref<F64>> {
502    match self {
503      Value::U8(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
504      Value::U16(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
505      Value::U32(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
506      Value::U64(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
507      Value::U128(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
508      Value::I8(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
509      Value::I16(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
510      Value::I32(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
511      Value::I64(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
512      Value::I128(v) => Some(new_ref(F64::new(*v.borrow() as f64))),
513      Value::F64(v) => Some(new_ref(F64::new((*v.borrow()).0 as f64))),
514      Value::F64(v) => Some(new_ref(F64::new((*v.borrow()).0 as f64))),
515      Value::MutableReference(val) => val.borrow().as_f64(),
516      _ => None,
517    }
518  }
519
520  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 }}
521  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 }}
522  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 }}
523
524  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 }}
525  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 }}
526  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 }}
527  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 }}
528  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 }}
529
530  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 }}
531  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 }}
532  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 }}
533  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 }}
534  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 }}
535
536  pub fn as_vecusize(&self) -> Option<Vec<usize>> {
537    match self {
538      Value::MatrixIndex(v) => Some(v.as_vec()),
539      Value::MatrixI64(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::<Vec<usize>>()),
540      Value::MatrixF64(v) => Some(v.as_vec().iter().map(|x| (*x).0 as usize).collect::<Vec<usize>>()),
541      Value::MutableReference(x) => x.borrow().as_vecusize(),
542      Value::MatrixBool(_) => None,
543      Value::Bool(_) => None,
544      _ => todo!(),
545    }
546  }
547
548  pub fn as_index(&self) -> MResult<Value> {
549    match self.as_usize() {      
550      Some(ix) => Ok(Value::Index(new_ref(ix))),
551      None => match self.as_vecusize() {
552        Some(x) => {
553          let shape = self.shape();
554          let out = Value::MatrixIndex(usize::to_matrix(x, shape[0] * shape[1],1 ));
555          Ok(out)
556        },
557        None => match self.as_vecbool() {
558          Some(x) => {
559            let shape = self.shape();
560            let out = match (shape[0], shape[1]) {
561              (1,1) => Value::Bool(new_ref(x[0])),
562              (1,n) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
563              (m,1) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
564              (m,n) => Value::MatrixBool(Matrix::DVector(new_ref(DVector::from_vec(x)))),
565            };
566            Ok(out)
567          }
568          None => match self.as_bool() {
569            Some(x) => Ok(Value::Bool(x)),
570            None => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledIndexKind}),
571          }
572        }
573      }
574    }
575  }
576
577  pub fn as_usize(&self) -> Option<usize> {
578    match self {      
579      Value::Index(v) => Some(*v.borrow()),
580      Value::U8(v) => Some(*v.borrow() as usize),
581      Value::U16(v) => Some(*v.borrow() as usize),
582      Value::U32(v) => Some(*v.borrow() as usize),
583      Value::U64(v) => Some(*v.borrow() as usize),
584      Value::U128(v) => Some(*v.borrow() as usize),
585      Value::I8(v) => Some(*v.borrow() as usize),
586      Value::I16(v) => Some(*v.borrow() as usize),
587      Value::I32(v) => Some(*v.borrow() as usize),
588      Value::I64(v) => Some(*v.borrow() as usize),
589      Value::I128(v) => Some(*v.borrow() as usize),
590      Value::F32(v) => Some((*v.borrow()).0 as usize),
591      Value::F64(v) => Some((*v.borrow()).0 as usize),
592      Value::Id(v) => Some(*v as usize),
593      Value::MutableReference(v) => v.borrow().as_usize(),
594      _ => None,
595    }
596  }
597
598}
599
600pub trait ToIndex {
601  fn to_index(&self) -> Value;
602}
603
604impl ToIndex for Ref<Vec<i64>> { fn to_index(&self) -> Value { (*self.borrow()).iter().map(|x| *x as usize).collect::<Vec<usize>>().to_value() } }
605
606pub trait ToValue {
607  fn to_value(&self) -> Value;
608}
609
610impl ToValue for Vec<usize> {
611  fn to_value(&self) -> Value {
612    match self.len() {
613      1 => Value::Index(new_ref(self[0].clone())),
614      //2 => Value::MatrixIndex(Matrix::RowVector2(new_ref(RowVector2::from_vec(self.clone())))),
615      //3 => Value::MatrixIndex(Matrix::RowVector3(new_ref(RowVector3::from_vec(self.clone())))),
616      //4 => Value::MatrixIndex(Matrix::RowVector4(new_ref(RowVector4::from_vec(self.clone())))),
617      n => Value::MatrixIndex(Matrix::DVector(new_ref(DVector::from_vec(self.clone())))),
618    }
619  }
620}
621
622impl ToValue for Ref<usize> { fn to_value(&self) -> Value { Value::Index(self.clone()) } }
623impl ToValue for Ref<u8>    { fn to_value(&self) -> Value { Value::U8(self.clone())    } }
624impl ToValue for Ref<u16>   { fn to_value(&self) -> Value { Value::U16(self.clone())   } }
625impl ToValue for Ref<u32>   { fn to_value(&self) -> Value { Value::U32(self.clone())   } }
626impl ToValue for Ref<u64>   { fn to_value(&self) -> Value { Value::U64(self.clone())   } }
627impl ToValue for Ref<u128>  { fn to_value(&self) -> Value { Value::U128(self.clone())  } }
628impl ToValue for Ref<i8>    { fn to_value(&self) -> Value { Value::I8(self.clone())    } }
629impl ToValue for Ref<i16>   { fn to_value(&self) -> Value { Value::I16(self.clone())   } }
630impl ToValue for Ref<i32>   { fn to_value(&self) -> Value { Value::I32(self.clone())   } }
631impl ToValue for Ref<i64>   { fn to_value(&self) -> Value { Value::I64(self.clone())   } }
632impl ToValue for Ref<i128>  { fn to_value(&self) -> Value { Value::I128(self.clone())  } }
633impl ToValue for Ref<F32>   { fn to_value(&self) -> Value { Value::F32(self.clone())   } }
634impl ToValue for Ref<F64>   { fn to_value(&self) -> Value { Value::F64(self.clone())   } }
635impl ToValue for Ref<bool>  { fn to_value(&self) -> Value { Value::Bool(self.clone())  } }
636
637macro_rules! to_value_matrix {
638  ($($nd_matrix_kind:ident, $matrix_kind:ident, $base_type:ty),+ $(,)?) => {
639    $(
640      impl ToValue for Ref<$nd_matrix_kind<$base_type>> {
641        fn to_value(&self) -> Value {
642          Value::$matrix_kind(Matrix::<$base_type>::$nd_matrix_kind(self.clone()))
643        }
644      }
645    )+
646  };}
647
648macro_rules! impl_to_value_matrix {
649  ($matrix_kind:ident) => {
650    to_value_matrix!(
651      $matrix_kind, MatrixIndex, usize,
652      $matrix_kind, MatrixBool,  bool,
653      $matrix_kind, MatrixI8,    i8,
654      $matrix_kind, MatrixI16,   i16,
655      $matrix_kind, MatrixI32,   i32,
656      $matrix_kind, MatrixI64,   i64,
657      $matrix_kind, MatrixI128,  i128,
658      $matrix_kind, MatrixU8,    u8,
659      $matrix_kind, MatrixU16,   u16,
660      $matrix_kind, MatrixU32,   u32,
661      $matrix_kind, MatrixU64,   u64,
662      $matrix_kind, MatrixU128,  u128,
663      $matrix_kind, MatrixF32,   F32,
664      $matrix_kind, MatrixF64,   F64,
665    );
666  }
667}
668
669impl_to_value_matrix!(Matrix2x3);
670impl_to_value_matrix!(Matrix3x2);
671impl_to_value_matrix!(Matrix1);
672impl_to_value_matrix!(Matrix2);
673impl_to_value_matrix!(Matrix3);
674impl_to_value_matrix!(Matrix4);
675impl_to_value_matrix!(Vector2);
676impl_to_value_matrix!(Vector3);
677impl_to_value_matrix!(Vector4);
678impl_to_value_matrix!(RowVector2);
679impl_to_value_matrix!(RowVector3);
680impl_to_value_matrix!(RowVector4);
681impl_to_value_matrix!(RowDVector);
682impl_to_value_matrix!(DVector);
683impl_to_value_matrix!(DMatrix);
684
685// Set --------------------------------------------------------------------------
686
687#[derive(Clone, Debug, PartialEq, Eq)]
688pub struct MechSet {
689  pub kind: ValueKind,
690  pub num_elements: usize,
691  pub set: IndexSet<Value>,
692}
693
694impl MechSet {
695
696  pub fn kind(&self) -> ValueKind {
697    ValueKind::Set(Box::new(self.kind.clone()), self.num_elements)
698  }
699
700  pub fn from_vec(vec: Vec<Value>) -> MechSet {
701    let mut set = IndexSet::new();
702    for v in vec {
703      set.insert(v);
704    }
705    let kind = if set.len() > 0 { set.iter().next().unwrap().kind() } else { ValueKind::Empty };
706    MechSet{
707      kind,
708      num_elements: set.len(),
709      set}
710  }
711
712  pub fn pretty_print(&self) -> String {
713    let mut builder = Builder::default();
714    let mut element_strings = vec![];
715    for x in self.set.iter() {
716      element_strings.push(x.pretty_print());
717    }
718    builder.push_record(element_strings);
719    let mut table = builder.build();
720    table.with(Style::modern_rounded());
721    format!("{table}")
722  }
723
724}
725
726impl Hash for MechSet {
727  fn hash<H: Hasher>(&self, state: &mut H) {
728    for x in self.set.iter() {
729      x.hash(state)
730    }
731  }
732}
733
734// Map ------------------------------------------------------------------
735
736#[derive(Clone, Debug, PartialEq, Eq)]
737pub struct MechMap {
738  pub key_kind: ValueKind,
739  pub value_kind: ValueKind,
740  pub num_elements: usize,
741  pub map: IndexMap<Value,Value>,
742}
743
744impl MechMap {
745
746  pub fn kind(&self) -> ValueKind {
747    ValueKind::Map(Box::new(self.key_kind.clone()), Box::new(self.value_kind.clone()))
748  }
749
750  pub fn pretty_print(&self) -> String {
751    let mut builder = Builder::default();
752    let mut element_strings = vec![];
753    let mut key_strings = vec![];
754    for (k,v) in self.map.iter() {
755      element_strings.push(v.pretty_print());
756      key_strings.push(k.pretty_print());
757    }    
758    builder.push_record(key_strings);
759    builder.push_record(element_strings);
760    let mut table = builder.build();
761    table.with(Style::modern_rounded());
762    format!("{table}")
763  }
764
765  pub fn from_vec(vec: Vec<(Value,Value)>) -> MechMap {
766    let mut map = IndexMap::new();
767    for (k,v) in vec {
768      map.insert(k,v);
769    }
770    MechMap{
771      key_kind: map.keys().next().unwrap().kind(),
772      value_kind: map.values().next().unwrap().kind(),
773      num_elements: map.len(),
774      map}
775  }
776}
777
778impl Hash for MechMap {
779  fn hash<H: Hasher>(&self, state: &mut H) {
780    for x in self.map.iter() {
781      x.hash(state)
782    }
783  }
784}
785
786// Table ------------------------------------------------------------------
787
788#[derive(Clone, Debug, PartialEq, Eq)]
789pub struct MechTable {
790  rows: usize,
791  cols: usize,
792  data: IndexMap<Value,(ValueKind,Matrix<Value>)>,
793  col_names: HashMap<Value,String>,
794}
795
796impl MechTable {
797
798  pub fn new(rows: usize, cols: usize, data: IndexMap<Value,(ValueKind,Matrix<Value>)>, col_names: HashMap<Value,String>) -> MechTable {
799    MechTable{rows, cols, data, col_names}
800  }
801
802  pub fn kind(&self) -> ValueKind {
803    ValueKind::Table(
804      self.data.iter().map(|(_,v)| v.0.clone()).collect(),
805      self.rows)
806  }
807
808  pub fn rows(&self) -> usize {
809    self.rows
810  }
811
812  pub fn cols(&self) -> usize {
813    self.cols
814  }
815
816  pub fn get(&self, key: &Value) -> Option<&(ValueKind,Matrix<Value>)> {
817    self.data.get(key)
818  }
819
820  pub fn pretty_print(&self) -> String {
821    let mut builder = Builder::default();
822    for (k,(knd,val)) in &self.data {
823      let name = self.col_names.get(k).unwrap();
824      let mut col_string = vec![format!("{}<{}>", name.to_string(), knd), val.pretty_print()];
825      builder.push_column(col_string);
826    }
827    let mut table = builder.build();
828    table.with(Style::modern_rounded());
829    format!("{table}")
830  }
831
832  pub fn shape(&self) -> Vec<usize> {
833    vec![self.rows,self.cols]
834  }
835}
836
837impl Hash for MechTable {
838  fn hash<H: Hasher>(&self, state: &mut H) {
839    for (k,(knd,val)) in self.data.iter() {
840      k.hash(state);
841      knd.hash(state);
842      val.hash(state);
843    }
844  }
845}
846
847// Record ------------------------------------------------------------------
848
849#[derive(Clone, Debug, PartialEq, Eq)]
850pub struct MechRecord {
851  pub cols: usize,
852  pub kinds: Vec<ValueKind>,
853  pub data: IndexMap<u64,Value>,
854}
855
856impl MechRecord {
857
858  pub fn get(&self, key: &u64) -> Option<&Value> {
859    self.data.get(key)
860  }
861
862  pub fn from_vec(vec: Vec<(u64,Value)>) -> MechRecord {
863    let mut data = IndexMap::new();
864    for (k,v) in vec {
865      data.insert(k,v);
866    }
867    let kinds = data.iter().map(|(_,v)| v.kind()).collect();
868    MechRecord{cols: data.len(), kinds, data}
869  }
870
871  pub fn insert_field(&mut self, key: u64, value: Value) {
872    self.cols += 1;
873    self.kinds.push(value.kind());
874    self.data.insert(key, value);
875  }
876
877  pub fn kind(&self) -> ValueKind {
878    ValueKind::Record(self.kinds.clone())
879  }
880
881  pub fn pretty_print(&self) -> String {
882    let mut builder = Builder::default();
883    let mut key_strings = vec![];
884    let mut element_strings = vec![];
885    for (k,v) in &self.data {
886      key_strings.push(format!("{:?}",humanize(k)));
887      element_strings.push(v.pretty_print());
888    }
889    builder.push_record(key_strings);
890    builder.push_record(element_strings);
891    let mut table = builder.build();
892    table.with(Style::modern_rounded());
893    format!("{table}")
894  }
895
896  pub fn shape(&self) -> Vec<usize> {
897    vec![1,self.cols]
898  }
899}
900
901impl Hash for MechRecord {
902  fn hash<H: Hasher>(&self, state: &mut H) {
903    for (k,v) in self.data.iter() {
904      k.hash(state);
905      v.hash(state);
906    }
907  }
908}
909
910// Tuple ----------------------------------------------------------------------
911
912#[derive(Clone, Debug, PartialEq, Eq)]
913pub struct MechTuple {
914  pub elements: Vec<Box<Value>>
915}
916
917impl MechTuple {
918
919  pub fn pretty_print(&self) -> String {
920    let mut builder = Builder::default();
921    let string_elements: Vec<String> = self.elements.iter().map(|e| e.pretty_print()).collect::<Vec<String>>();
922    builder.push_record(string_elements);
923    let mut table = builder.build();
924    table.with(Style::modern_rounded());
925    format!("{table}")
926  }
927
928  pub fn from_vec(elements: Vec<Value>) -> Self {
929    MechTuple{elements: elements.iter().map(|m| Box::new(m.clone())).collect::<Vec<Box<Value>>>()}
930  }
931
932  pub fn size(&self) -> usize {
933    self.elements.len()
934  }
935
936  pub fn kind(&self) -> ValueKind {
937    ValueKind::Tuple(self.elements.iter().map(|x| x.kind()).collect())
938  }
939
940}
941
942impl Hash for MechTuple {
943  fn hash<H: Hasher>(&self, state: &mut H) {
944    for x in self.elements.iter() {
945        x.hash(state)
946    }
947  }
948}
949
950// Enum -----------------------------------------------------------------------
951
952#[derive(Clone, Debug, PartialEq, Eq)]
953pub struct MechEnum {
954  pub id: u64,
955  pub variants: Vec<(u64, Option<Value>)>,
956}
957
958impl MechEnum {
959
960  pub fn kind(&self) -> ValueKind {
961    ValueKind::Enum(self.id)
962  }
963
964  pub fn pretty_print(&self) -> String {
965    let mut builder = Builder::default();
966    let string_elements: Vec<String> = vec![format!("{}{:?}",self.id,self.variants)];
967    builder.push_record(string_elements);
968    let mut table = builder.build();
969    table.with(Style::modern_rounded());
970    format!("{table}")
971  }
972
973}
974
975impl Hash for MechEnum {
976  fn hash<H: Hasher>(&self, state: &mut H) {
977    self.id.hash(state);
978    self.variants.hash(state);
979  }
980}