1use crate::matrix::Matrix;
2use crate::*;
3use crate::nodes::Matrix as Mat;
4use crate::{MechError, MechErrorKind, hash_str, nodes::Kind as NodeKind, nodes::*, humanize};
5use std::collections::HashMap;
6
7use na::{Vector3, DVector, Vector2, Vector4, RowDVector, Matrix1, Matrix3, Matrix4, RowVector3, RowVector4, RowVector2, DMatrix, Rotation3, Matrix2x3, Matrix3x2, Matrix6, Matrix2};
8use std::hash::{Hash, Hasher};
9use indexmap::set::IndexSet;
10use indexmap::map::*;
11use tabled::{
12 builder::Builder,
13 settings::{object::Rows,Panel, Span, Alignment, Modify, Style},
14 Tabled,
15};
16use paste::paste;
17use serde::ser::{Serialize, Serializer, SerializeStruct};
18use serde::de::{self, Deserialize, SeqAccess, Deserializer, MapAccess, Visitor};
19use std::fmt;
20use std::cell::RefCell;
21use std::rc::Rc;
22
23macro_rules! impl_as_type {
24 ($target_type:ty) => {
25 paste!{
26 pub fn [<as_ $target_type>](&self) -> Option<Ref<$target_type>> {
27 match self {
28 Value::U8(v) => Some(new_ref(*v.borrow() as $target_type)),
29 Value::U16(v) => Some(new_ref(*v.borrow() as $target_type)),
30 Value::U32(v) => Some(new_ref(*v.borrow() as $target_type)),
31 Value::U64(v) => Some(new_ref(*v.borrow() as $target_type)),
32 Value::U128(v) => Some(new_ref(*v.borrow() as $target_type)),
33 Value::I8(v) => Some(new_ref(*v.borrow() as $target_type)),
34 Value::I16(v) => Some(new_ref(*v.borrow() as $target_type)),
35 Value::I32(v) => Some(new_ref(*v.borrow() as $target_type)),
36 Value::I64(v) => Some(new_ref(*v.borrow() as $target_type)),
37 Value::I128(v) => Some(new_ref(*v.borrow() as $target_type)),
38 Value::F32(v) => Some(new_ref((*v.borrow()).0 as $target_type)),
39 Value::F64(v) => Some(new_ref((*v.borrow()).0 as $target_type)),
40 Value::MutableReference(val) => val.borrow().[<as_ $target_type>](),
41 _ => None,
42 }
43 }
44 }
45 };
46}
47
48#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
51pub enum ValueKind {
52 U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64,
53 String, Bool, Matrix(Box<ValueKind>,Vec<usize>), Enum(u64), Set(Box<ValueKind>, usize),
54 Map(Box<ValueKind>,Box<ValueKind>), Record(Vec<ValueKind>), Table(Vec<ValueKind>, usize), Tuple(Vec<ValueKind>), Id, Index, Reference(Box<ValueKind>), Atom(u64), Empty, Any
55}
56
57impl ValueKind {
58
59 pub fn deref_kind(&self) -> Option<ValueKind> {
60 match self {
61 ValueKind::Reference(x) => Some(*x.clone()),
62 _ => None,
63 }
64 }
65
66}
67
68impl std::fmt::Display for ValueKind {
69 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
70 match self {
71 ValueKind::U8 => write!(f, "u8"),
72 ValueKind::U16 => write!(f, "u16"),
73 ValueKind::U32 => write!(f, "u32"),
74 ValueKind::U64 => write!(f, "u64"),
75 ValueKind::U128 => write!(f, "u128"),
76 ValueKind::I8 => write!(f, "i8"),
77 ValueKind::I16 => write!(f, "i16"),
78 ValueKind::I32 => write!(f, "i32"),
79 ValueKind::I64 => write!(f, "i64"),
80 ValueKind::I128 => write!(f, "i128"),
81 ValueKind::F32 => write!(f, "f32"),
82 ValueKind::F64 => write!(f, "f64"),
83 ValueKind::String => write!(f, "string"),
84 ValueKind::Bool => write!(f, "bool"),
85 ValueKind::Matrix(x,s) => write!(f, "[{:?}]:{:?},{:?}",x,s[0],s[1]),
86 ValueKind::Enum(x) => write!(f, "{:?}",x),
87 ValueKind::Set(x,el) => write!(f, "{{{:?}}}:{}", x, el),
88 ValueKind::Map(x,y) => write!(f, "{{{:?}:{:?}}}",x,y),
89 ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
90 ValueKind::Table(x,y) => write!(f, "{{{}}}:{}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(","),y),
91 ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
92 ValueKind::Id => write!(f, "id"),
93 ValueKind::Index => write!(f, "ix"),
94 ValueKind::Reference(x) => write!(f, "{:?}",x),
95 ValueKind::Atom(x) => write!(f, "`{:?}",x),
96 ValueKind::Empty => write!(f, "_"),
97 ValueKind::Any => write!(f, "_"),
98 }
99 }
100}
101
102
103impl fmt::Debug for ValueKind {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 match self {
106 ValueKind::U8 => write!(f, "u8"),
107 ValueKind::U16 => write!(f, "u16"),
108 ValueKind::U32 => write!(f, "u32"),
109 ValueKind::U64 => write!(f, "u64"),
110 ValueKind::U128 => write!(f, "u128"),
111 ValueKind::I8 => write!(f, "i8"),
112 ValueKind::I16 => write!(f, "i16"),
113 ValueKind::I32 => write!(f, "i32"),
114 ValueKind::I64 => write!(f, "i64"),
115 ValueKind::I128 => write!(f, "i128"),
116 ValueKind::F32 => write!(f, "f32"),
117 ValueKind::F64 => write!(f, "f64"),
118 ValueKind::String => write!(f, "string"),
119 ValueKind::Bool => write!(f, "bool"),
120 ValueKind::Matrix(x,s) => {
121 let s = if s.len() == 2 { s.clone() } else if s.len() == 1 { vec![s[0], 1] } else { vec![0, 0] };
122 write!(f, "[{:?}]:{:?},{:?}",x,s[0],s[1]).clone()
123 }
124 ValueKind::Enum(x) => write!(f, "{:?}",x),
125 ValueKind::Set(x,el) => write!(f, "{{{:?}}}:{}", x, el),
126 ValueKind::Map(x,y) => write!(f, "{{{:?}:{:?}}}",x,y),
127 ValueKind::Record(x) => write!(f, "{{{}}}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
128 ValueKind::Table(x,y) => write!(f, "{{{}}}:{}",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(","),y),
129 ValueKind::Tuple(x) => write!(f, "({})",x.iter().map(|x| format!("{:?}",x)).collect::<Vec<String>>().join(",")),
130 ValueKind::Id => write!(f, "id"),
131 ValueKind::Index => write!(f, "ix"),
132 ValueKind::Reference(x) => write!(f, "&{:?}",x),
133 ValueKind::Atom(x) => write!(f, "`{:?}",x),
134 ValueKind::Empty => write!(f, "_"),
135 ValueKind::Any => write!(f, "_"),
136 }
137 }
138}
139
140impl ValueKind {
141 pub fn is_compatible(k1: ValueKind, k2: ValueKind) -> bool {
142 match k1 {
143 ValueKind::Reference(x) => {
144 ValueKind::is_compatible(*x,k2)
145 }
146 ValueKind::Matrix(x,_) => {
147 *x == k2
148 }
149 x => x == k2,
150 }
151 }
152}
153
154#[derive(Clone, Debug, PartialEq, Eq)]
155pub enum Value {
156 U8(Ref<u8>),
157 U16(Ref<u16>),
158 U32(Ref<u32>),
159 U64(Ref<u64>),
160 U128(Ref<u128>),
161 I8(Ref<i8>),
162 I16(Ref<i16>),
163 I32(Ref<i32>),
164 I64(Ref<i64>),
165 I128(Ref<i128>),
166 F32(Ref<F32>),
167 F64(Ref<F64>),
168 String(Ref<String>),
169 Bool(Ref<bool>),
170 Atom(u64),
171 MatrixIndex(Matrix<usize>),
172 MatrixBool(Matrix<bool>),
173 MatrixU8(Matrix<u8>),
174 MatrixU16(Matrix<u16>),
175 MatrixU32(Matrix<u32>),
176 MatrixU64(Matrix<u64>),
177 MatrixU128(Matrix<u128>),
178 MatrixI8(Matrix<i8>),
179 MatrixI16(Matrix<i16>),
180 MatrixI32(Matrix<i32>),
181 MatrixI64(Matrix<i64>),
182 MatrixI128(Matrix<i128>),
183 MatrixF32(Matrix<F32>),
184 MatrixF64(Matrix<F64>),
185 MatrixString(Matrix<String>),
186 MatrixValue(Matrix<Value>),
187 Set(MechSet),
188 Map(MechMap),
189 Record(MechRecord),
190 Table(MechTable),
191 Tuple(MechTuple),
192 Enum(Box<MechEnum>),
193 Id(u64),
194 Index(Ref<usize>),
195 MutableReference(MutableReference),
196 Kind(ValueKind),
197 IndexAll,
198 Empty
199}
200
201impl fmt::Display for Value {
202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203 self.pretty_print().fmt(f)
204 }
205}
206
207impl Hash for Value {
208 fn hash<H: Hasher>(&self, state: &mut H) {
209 match self {
210 Value::Id(x) => x.hash(state),
211 Value::Kind(x) => x.hash(state),
212 Value::U8(x) => x.borrow().hash(state),
213 Value::U16(x) => x.borrow().hash(state),
214 Value::U32(x) => x.borrow().hash(state),
215 Value::U64(x) => x.borrow().hash(state),
216 Value::U128(x) => x.borrow().hash(state),
217 Value::I8(x) => x.borrow().hash(state),
218 Value::I16(x) => x.borrow().hash(state),
219 Value::I32(x) => x.borrow().hash(state),
220 Value::I64(x) => x.borrow().hash(state),
221 Value::I128(x) => x.borrow().hash(state),
222 Value::F32(x) => x.borrow().hash(state),
223 Value::F64(x) => x.borrow().hash(state),
224 Value::Index(x)=> x.borrow().hash(state),
225 Value::Bool(x) => x.borrow().hash(state),
226 Value::Atom(x) => x.hash(state),
227 Value::Set(x) => x.hash(state),
228 Value::Map(x) => x.hash(state),
229 Value::Table(x) => x.hash(state),
230 Value::Tuple(x) => x.hash(state),
231 Value::Record(x) => x.hash(state),
232 Value::Enum(x) => x.hash(state),
233 Value::String(x) => x.borrow().hash(state),
234 Value::MatrixBool(x) => x.hash(state),
235 Value::MatrixIndex(x) => x.hash(state),
236 Value::MatrixU8(x) => x.hash(state),
237 Value::MatrixU16(x) => x.hash(state),
238 Value::MatrixU32(x) => x.hash(state),
239 Value::MatrixU64(x) => x.hash(state),
240 Value::MatrixU128(x) => x.hash(state),
241 Value::MatrixI8(x) => x.hash(state),
242 Value::MatrixI16(x) => x.hash(state),
243 Value::MatrixI32(x) => x.hash(state),
244 Value::MatrixI64(x) => x.hash(state),
245 Value::MatrixI128(x) => x.hash(state),
246 Value::MatrixF32(x) => x.hash(state),
247 Value::MatrixF64(x) => x.hash(state),
248 Value::MatrixString(x) => x.hash(state),
249 Value::MatrixValue(x) => x.hash(state),
250 Value::MutableReference(x) => x.borrow().hash(state),
251 Value::Empty => Value::Empty.hash(state),
252 Value::IndexAll => Value::IndexAll.hash(state),
253 }
254 }
255}
256
257impl Value {
258
259 pub fn size_of(&self) -> usize {
260 match self {
261 Value::U8(x) => 1,
262 Value::U16(x) => 2,
263 Value::U32(x) => 4,
264 Value::U64(x) => 8,
265 Value::U128(x) => 16,
266 Value::I8(x) => 1,
267 Value::I16(x) => 2,
268 Value::I32(x) => 4,
269 Value::I64(x) => 8,
270 Value::I128(x) => 16,
271 Value::F32(x) => 4,
272 Value::F64(x) => 8,
273 Value::Bool(x) => 1,
274 Value::MatrixIndex(x) =>x.size_of(),
275 Value::MatrixBool(x) =>x.size_of(),
276 Value::MatrixU8(x) => x.size_of(),
277 Value::MatrixU16(x) => x.size_of(),
278 Value::MatrixU32(x) => x.size_of(),
279 Value::MatrixU64(x) => x.size_of(),
280 Value::MatrixU128(x) => x.size_of(),
281 Value::MatrixI8(x) => x.size_of(),
282 Value::MatrixI16(x) => x.size_of(),
283 Value::MatrixI32(x) => x.size_of(),
284 Value::MatrixI64(x) => x.size_of(),
285 Value::MatrixI128(x) => x.size_of(),
286 Value::MatrixF32(x) => x.size_of(),
287 Value::MatrixF64(x) => x.size_of(),
288 Value::MatrixValue(x) => x.size_of(),
289 Value::MatrixString(x) => x.size_of(),
290 _ => 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 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#[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#[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#[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#[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#[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#[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}