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#[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 }
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 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#[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#[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#[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#[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#[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#[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}