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