1mod add;
2mod bitand;
3mod bitor;
4mod bitxor;
5mod div;
6mod error;
7mod logical;
8mod mul;
9mod neg;
10mod not;
11mod rem;
12mod reverse;
13mod shl;
14mod shr;
15mod sub;
16
17pub use error::VMError;
18use std::cell::RefCell;
19
20use crate::{impl_from, Number, RigzType, ValueRange};
21use indexmap::IndexMap;
22use serde::{Deserialize, Serialize};
23use std::cmp::Ordering;
24use std::fmt::{Display, Formatter};
25use std::hash::{Hash, Hasher};
26use std::rc::Rc;
27
28#[derive(Clone, Debug, Default, Serialize, Deserialize)]
29#[serde(untagged)]
30pub enum Value {
31 #[default]
32 None,
33 Bool(bool),
34 Number(Number),
35 String(String),
36 List(Vec<Value>),
38 Map(IndexMap<Value, Value>),
39 Range(ValueRange),
40 Error(VMError),
41 Tuple(Vec<Value>),
42 Type(RigzType),
44}
45
46impl From<Value> for Rc<RefCell<Value>> {
47 #[inline]
48 fn from(value: Value) -> Self {
49 Rc::new(RefCell::new(value))
50 }
51}
52
53impl_from! {
54 bool, Value, Value::Bool;
55 String, Value, Value::String;
56 VMError, Value, Value::Error;
57 ValueRange, Value, Value::Range;
58 RigzType, Value, Value::Type;
59}
60
61impl From<&'_ str> for Value {
62 #[inline]
63 fn from(value: &'_ str) -> Self {
64 Value::String(value.to_string())
65 }
66}
67
68impl<T: Into<Number>> From<T> for Value {
69 #[inline]
70 fn from(value: T) -> Self {
71 Value::Number(value.into())
72 }
73}
74
75impl<T: Into<Value>> From<Vec<T>> for Value {
76 #[inline]
77 fn from(value: Vec<T>) -> Self {
78 Value::List(value.into_iter().map(|v| v.into()).collect())
79 }
80}
81
82impl<K: Into<Value>, V: Into<Value>> From<IndexMap<K, V>> for Value {
83 #[inline]
84 fn from(value: IndexMap<K, V>) -> Self {
85 Value::Map(
86 value
87 .into_iter()
88 .map(|(k, v)| (k.into(), v.into()))
89 .collect(),
90 )
91 }
92}
93
94impl From<()> for Value {
95 #[inline]
96 fn from(_value: ()) -> Self {
97 Value::None
98 }
99}
100
101impl<A: Into<Value>, B: Into<Value>> From<(A, B)> for Value {
102 #[inline]
103 fn from(value: (A, B)) -> Self {
104 Value::Tuple(vec![value.0.into(), value.1.into()])
105 }
106}
107
108impl<A: Into<Value>, B: Into<Value>, C: Into<Value>> From<(A, B, C)> for Value {
109 #[inline]
110 fn from(value: (A, B, C)) -> Self {
111 Value::Tuple(vec![value.0.into(), value.1.into(), value.2.into()])
112 }
113}
114
115impl<A: Into<Value>, B: Into<Value>, C: Into<Value>, D: Into<Value>> From<(A, B, C, D)> for Value {
116 #[inline]
117 fn from(value: (A, B, C, D)) -> Self {
118 Value::Tuple(vec![
119 value.0.into(),
120 value.1.into(),
121 value.2.into(),
122 value.3.into(),
123 ])
124 }
125}
126
127impl<A: Into<Value>, B: Into<Value>, C: Into<Value>, D: Into<Value>, E: Into<Value>>
128 From<(A, B, C, D, E)> for Value
129{
130 #[inline]
131 fn from(value: (A, B, C, D, E)) -> Self {
132 Value::Tuple(vec![
133 value.0.into(),
134 value.1.into(),
135 value.2.into(),
136 value.3.into(),
137 value.4.into(),
138 ])
139 }
140}
141
142impl<V: Into<Value>> From<Option<V>> for Value {
143 #[inline]
144 fn from(value: Option<V>) -> Self {
145 match value {
146 None => Value::None,
147 Some(v) => v.into(),
148 }
149 }
150}
151
152impl<V: Into<Value>> From<Result<V, VMError>> for Value {
153 #[inline]
154 fn from(value: Result<V, VMError>) -> Self {
155 match value {
156 Ok(v) => v.into(),
157 Err(e) => e.into(),
158 }
159 }
160}
161
162impl Eq for Value {}
163
164impl PartialOrd for Value {
165 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
166 if self.eq(other) {
167 return Some(Ordering::Equal);
168 }
169
170 match (self, other) {
171 (Value::Error(_), _) => Some(Ordering::Less),
173 (_, Value::Error(_)) => Some(Ordering::Greater),
174 (Value::Type(a), Value::Type(b)) => a.partial_cmp(b),
175 (Value::Type(_), _) => Some(Ordering::Less),
176 (_, Value::Type(_)) => Some(Ordering::Greater),
177 (Value::None, _) => Some(Ordering::Less),
178 (_, Value::None) => Some(Ordering::Greater),
179 (Value::Bool(a), Value::Bool(b)) => a.partial_cmp(b),
180 (Value::Bool(_), _) => Some(Ordering::Less),
181 (_, Value::Bool(_)) => Some(Ordering::Greater),
182 (Value::Number(a), Value::Number(b)) => a.partial_cmp(b),
183 (Value::Number(_), _) => Some(Ordering::Less),
184 (_, Value::Number(_)) => Some(Ordering::Greater),
185 (Value::Range(a), Value::Range(b)) => a.partial_cmp(b),
186 (Value::Range(_), _) => Some(Ordering::Less),
187 (_, Value::Range(_)) => Some(Ordering::Greater),
188 (Value::String(a), Value::String(b)) => a.partial_cmp(b),
189 (Value::String(_), _) => Some(Ordering::Less),
190 (_, Value::String(_)) => Some(Ordering::Greater),
191 (Value::Tuple(a), Value::Tuple(b)) => a.partial_cmp(b),
192 (Value::Tuple(_), _) => Some(Ordering::Less),
193 (_, Value::Tuple(_)) => Some(Ordering::Greater),
194 (Value::List(a), Value::List(b)) => a.partial_cmp(b),
195 (Value::List(_), _) => Some(Ordering::Less),
196 (_, Value::List(_)) => Some(Ordering::Greater),
197 (Value::Map(a), Value::Map(b)) => a.into_iter().partial_cmp(b),
198 }
199 }
200}
201
202impl Value {
203 #[inline]
204 pub fn to_number(&self) -> Result<Number, VMError> {
205 match self {
206 Value::None => Ok(Number::zero()),
207 Value::Bool(b) => {
208 let n = if *b { Number::one() } else { Number::zero() };
209 Ok(n)
210 }
211 Value::Number(n) => Ok(*n),
212 Value::String(s) => match s.parse() {
213 Ok(n) => Ok(n),
214 Err(e) => Err(VMError::ConversionError(format!(
215 "Cannot convert {s} to Number: {e}"
216 ))),
217 },
218 v => Err(VMError::ConversionError(format!(
219 "Cannot convert {v} to Number"
220 ))),
221 }
222 }
223
224 #[inline]
225 pub fn to_float(&self) -> Result<f64, VMError> {
226 Ok(self.to_number()?.to_float())
227 }
228
229 #[inline]
230 pub fn to_int(&self) -> Result<i64, VMError> {
231 Ok(self.to_number()?.to_int())
232 }
233
234 #[inline]
235 pub fn to_usize(&self) -> Result<usize, VMError> {
236 self.to_number()?.to_usize()
237 }
238
239 pub fn as_bool(&mut self) -> &mut bool {
240 if let Value::Bool(m) = self {
241 return m;
242 }
243
244 *self = Value::Bool(self.to_bool());
245 self.as_bool()
246 }
247
248 pub fn as_float(&mut self) -> Result<&mut f64, VMError> {
249 if let Value::Number(m) = self {
250 return match m {
251 Number::Int(_) => {
252 *m = Number::Float(m.to_float());
253 let Number::Float(f) = m else { unreachable!() };
254 Ok(f)
255 }
256 Number::Float(f) => Ok(f),
257 };
258 }
259
260 *self = Value::Number(Number::Float(self.to_float()?));
261 self.as_float()
262 }
263
264 pub fn as_number(&mut self) -> Result<&mut Number, VMError> {
265 if let Value::Number(m) = self {
266 return Ok(m);
267 }
268
269 *self = Value::Number(self.to_number()?);
270 self.as_number()
271 }
272
273 pub fn as_int(&mut self) -> Result<&mut i64, VMError> {
274 if let Value::Number(m) = self {
275 return match m {
276 Number::Int(i) => Ok(i),
277 Number::Float(_) => {
278 *m = Number::Int(m.to_int());
279 let Number::Int(i) = m else { unreachable!() };
280 Ok(i)
281 }
282 };
283 }
284
285 *self = Value::Number(Number::Int(self.to_int()?));
286 self.as_int()
287 }
288
289 pub fn as_string(&mut self) -> &mut String {
290 if let Value::String(m) = self {
291 return m;
292 }
293
294 *self = Value::String(self.to_string());
295 self.as_string()
296 }
297
298 pub fn as_map(&mut self) -> &mut IndexMap<Value, Value> {
299 if let Value::Map(m) = self {
300 return m;
301 }
302
303 *self = Value::Map(self.to_map());
304 self.as_map()
305 }
306
307 pub fn as_list(&mut self) -> &mut Vec<Value> {
308 if let Value::List(m) = self {
309 return m;
310 }
311
312 *self = Value::List(self.to_list());
313 self.as_list()
314 }
315
316 #[inline]
317 pub fn to_bool(&self) -> bool {
318 match self {
319 Value::None => false,
320 Value::Error(_) => false,
321 Value::Type(_) => false,
322 Value::Bool(b) => *b,
323 Value::Number(n) => !n.is_zero(),
324 Value::String(s) => {
325 let empty = s.is_empty();
326 if empty {
327 return false;
328 }
329
330 s.parse().unwrap_or(true)
331 }
332 Value::Tuple(l) => !l.is_empty(),
333 Value::List(l) => !l.is_empty(),
334 Value::Map(m) => !m.is_empty(),
335 Value::Range(r) => !r.is_empty(),
336 }
337 }
338
339 pub fn to_list(&self) -> Vec<Value> {
340 match self {
341 Value::None => vec![],
342 Value::Bool(b) => {
343 if *b {
344 vec![Value::Bool(*b)]
345 } else {
346 vec![]
347 }
348 }
349 Value::Number(n) => {
350 vec![(*n).into()]
351 }
352 Value::String(s) => s.chars().map(|c| Value::String(c.to_string())).collect(),
353 Value::List(l) | Value::Tuple(l) => l.clone(),
354 Value::Map(m) => {
355 let mut result = Vec::with_capacity(m.len());
356 for (k, v) in m {
357 match k {
358 Value::Number(i) => match i.to_usize() {
359 Ok(index) => {
360 result.insert(index, v.clone());
361 }
362 Err(_) => return vec![Value::Map(m.clone())],
363 },
364 _ => return vec![Value::Map(m.clone())],
365 }
366 }
367 result
368 }
369 Value::Range(r) => r.to_list(),
370 Value::Error(e) => vec![Value::Error(e.clone())],
371 Value::Type(e) => vec![Value::Type(e.clone())],
372 }
373 }
374
375 pub fn to_map(&self) -> IndexMap<Value, Value> {
376 match self {
377 Value::None => IndexMap::new(),
378 Value::Bool(b) => {
379 if *b {
380 IndexMap::from([(Value::Bool(*b), Value::Bool(*b))])
381 } else {
382 IndexMap::new()
383 }
384 }
385 Value::Number(n) => IndexMap::from([((*n).into(), (*n).into())]),
386 Value::String(s) => {
387 let s = s.clone();
388 IndexMap::from([(s.clone().into(), s.into())])
389 }
390 Value::List(l) => l.iter().map(|v| (v.clone(), v.clone())).collect(),
391 Value::Tuple(l) => l
392 .chunks(2)
393 .map(|v| {
394 let [k, v] = v else {
395 return (v[0].clone(), Value::None);
396 };
397 (k.clone(), v.clone())
398 })
399 .collect(),
400 Value::Map(m) => m.clone(),
401 Value::Error(e) => {
402 let e = e.clone();
403 IndexMap::from([(e.clone().into(), e.into())])
404 }
405 Value::Type(e) => {
406 let e = e.clone();
407 IndexMap::from([(e.clone().into(), e.into())])
408 }
409 Value::Range(r) => r.to_map(),
410 }
411 }
412
413 #[inline]
414 pub fn rigz_type(&self) -> RigzType {
415 match self {
416 Value::None => RigzType::None,
417 Value::Bool(_) => RigzType::Bool,
418 Value::Number(_) => RigzType::Number,
419 Value::String(_) => RigzType::String,
420 Value::List(_) => RigzType::List(Box::new(RigzType::Any)),
422 Value::Map(_) => RigzType::Map(Box::new(RigzType::Any), Box::new(RigzType::Any)),
423 Value::Range(_) => RigzType::Range,
424 Value::Error(_) => RigzType::Error,
425 Value::Tuple(v) => RigzType::Tuple(v.iter().map(|v| v.rigz_type()).collect()),
426 Value::Type(r) => r.clone(),
427 }
428 }
429
430 #[inline]
431 pub fn cast(&self, rigz_type: &RigzType) -> Value {
432 match (self, rigz_type) {
433 (s, RigzType::Error) => Value::Error(VMError::RuntimeError(s.to_string())),
434 (_, RigzType::None) => Value::None,
435 (v, RigzType::Bool) => Value::Bool(v.to_bool()),
436 (v, RigzType::String) => Value::String(v.to_string()),
437 (v, RigzType::Number) => match v.to_number() {
438 Err(e) => e.into(),
439 Ok(n) => n.into(),
440 },
441 (s, RigzType::Any) => s.clone(),
442 (v, RigzType::Int) => match v.to_int() {
443 Err(_) => {
444 VMError::ConversionError(format!("Cannot convert {} to Int", v)).to_value()
445 }
446 Ok(n) => n.into(),
447 },
448 (v, RigzType::Float) => match v.to_float() {
449 Err(_) => {
450 VMError::ConversionError(format!("Cannot convert {} to Float", v)).to_value()
451 }
452 Ok(n) => n.into(),
453 },
454 (v, RigzType::List(_)) => Value::List(v.to_list()),
455 (v, RigzType::Map(_, _)) => Value::Map(v.to_map()),
456 (v, RigzType::Custom(def)) => {
457 let mut res = v.to_map();
458 for (field, rigz_type) in &def.fields {
459 match res.get_mut(&Value::String(field.clone())) {
460 None => {
461 return VMError::ConversionError(format!(
462 "Cannot convert value {} to {}, missing {}",
463 v, def.name, field
464 ))
465 .to_value()
466 }
467 Some(current) => *current = current.clone().cast(rigz_type),
468 }
469 }
470 Value::Map(res)
471 }
472 (v, t) => VMError::ConversionError(format!("Cannot convert value {} to {:?}", v, t))
473 .to_value(),
474 }
475 }
476
477 pub fn get(&self, attr: &Value) -> Result<Option<Value>, VMError> {
478 let v = match (self, attr) {
479 (Value::String(source), Value::Number(n)) => match n.to_usize() {
481 Ok(index) => match source.chars().nth(index) {
482 None => return Ok(None),
483 Some(c) => Value::String(c.to_string()),
484 },
485 Err(e) => e.into(),
486 },
487 (Value::List(source), Value::Number(n)) | (Value::Tuple(source), Value::Number(n)) => {
488 match n.to_usize() {
489 Ok(index) => match source.get(index) {
490 None => return Ok(None),
491 Some(c) => c.clone(),
492 },
493 Err(e) => e.into(),
494 }
495 }
496 (Value::Map(source), index) => match source.get(index) {
497 None => {
498 if let Value::Number(index) = index {
499 if let Ok(index) = index.to_usize() {
500 return Ok(source
501 .get_index(index)
502 .map(|(k, v)| Value::Tuple(vec![k.clone(), v.clone()])));
503 }
504 }
505 return Ok(None);
506 }
507 Some(c) => c.clone(),
508 },
509 (Value::Number(source), Value::Number(n)) => {
510 Value::Bool(source.to_bits() & (1 << n.to_int()) != 0)
511 }
512 (source, attr) => {
513 return Err(VMError::UnsupportedOperation(format!(
514 "Cannot read {} for {}",
515 attr, source
516 )))
517 }
518 };
519 Ok(Some(v))
520 }
521}
522
523impl Display for Value {
524 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
525 match self {
526 Value::None => write!(f, "none"),
527 Value::Error(e) => write!(f, "{}", e),
529 Value::Type(e) => write!(f, "{}", e),
530 Value::Bool(v) => write!(f, "{}", v),
531 Value::Number(v) => write!(f, "{}", v),
532 Value::String(v) => write!(f, "{}", v),
533 Value::Range(v) => write!(f, "{}", v),
534 Value::List(l) => {
535 let mut values = String::new();
536 let len = l.len();
537 for (index, v) in l.iter().enumerate() {
538 values.push_str(v.to_string().as_str());
539 if index != len - 1 {
540 values.push(',')
541 }
542 }
543 write!(f, "[{}]", values)
544 }
545 Value::Tuple(l) => {
546 let mut values = String::new();
547 let len = l.len();
548 for (index, v) in l.iter().enumerate() {
549 values.push_str(v.to_string().as_str());
550 if index != len - 1 {
551 values.push(',')
552 }
553 }
554 write!(f, "({})", values)
555 }
556 Value::Map(m) => {
557 let mut values = String::new();
558 let len = m.len();
559 for (index, (k, v)) in m.iter().enumerate() {
560 values.push_str(k.to_string().as_str());
561 values.push_str(" = ");
562 values.push_str(v.to_string().as_str());
563 if index != len - 1 {
564 values.push(',')
565 }
566 }
567 write!(f, "{{{}}}", values)
568 }
569 }
570 }
571}
572
573impl Hash for Value {
574 fn hash<H: Hasher>(&self, state: &mut H) {
575 match self {
576 Value::None => 0.hash(state),
577 Value::Error(e) => e.hash(state),
578 Value::Type(e) => e.hash(state),
579 Value::Bool(b) => b.hash(state),
580 Value::Number(n) => n.hash(state),
581 Value::String(s) => s.hash(state),
582 Value::Range(s) => s.hash(state),
583 Value::List(l) | Value::Tuple(l) => {
584 for v in l {
585 v.hash(state);
586 }
587 }
588 Value::Map(m) => {
589 for (k, v) in m {
590 k.hash(state);
591 v.hash(state);
592 }
593 }
594 }
595 }
596}
597
598impl PartialEq for Value {
599 fn eq(&self, other: &Self) -> bool {
600 match (self, other) {
601 (Value::None, Value::None) => true,
602 (Value::Error(a), Value::Error(b)) => *a == *b,
603 (Value::Type(a), Value::Type(b)) => *a == *b,
604 (Value::None, Value::Bool(false)) => true,
605 (Value::None, Value::Number(n)) => n.is_zero(),
606 (Value::Bool(false), Value::Number(n)) => n.is_zero(),
607 (Value::None, Value::String(s)) => s.is_empty() || s.eq("none"),
608 (Value::None, Value::List(v)) => v.is_empty(),
609 (Value::None, Value::Map(m)) => m.is_empty(),
610 (Value::Bool(false), Value::String(s)) => s.is_empty() || s.eq("false"),
611 (Value::Bool(false), Value::List(v)) => v.is_empty(),
612 (Value::Bool(false), Value::Map(m)) => m.is_empty(),
613 (Value::Bool(true), Value::String(s)) => s.eq("true"),
614 (Value::Bool(true), Value::Number(n)) => n.is_one(),
615 (Value::Bool(false), Value::None) => true,
616 (&Value::Bool(a), &Value::Bool(b)) => a == b,
617 (Value::Number(n), Value::None) => n.is_zero(),
618 (Value::Number(n), Value::Bool(false)) => n.is_zero(),
619 (Value::String(s), Value::None) => s.is_empty() || s.eq("none"),
620 (Value::List(v), Value::None) => v.is_empty(),
621 (Value::Map(m), Value::None) => m.is_empty(),
622 (Value::String(s), Value::Bool(false)) => s.is_empty() || s.eq("false"),
623 (Value::List(v), Value::Bool(false)) => v.is_empty(),
624 (Value::Map(m), Value::Bool(false)) => m.is_empty(),
625 (Value::String(s), Value::Bool(true)) => s.eq("true"),
626 (Value::Number(n), Value::Bool(true)) => n.is_one(),
627 (&Value::Number(a), &Value::Number(b)) => a == b,
628 (Value::Range(a), Value::Range(b)) => a == b,
629 (Value::String(a), Value::String(b)) => *a == *b,
630 (Value::Tuple(a), Value::List(b)) | (Value::List(a), Value::Tuple(b)) => *a == *b,
631 (Value::List(a), Value::List(b)) | (Value::Tuple(a), Value::Tuple(b)) => *a == *b,
632 (Value::Map(a), Value::Map(b)) => *a == *b,
633 (Value::Number(n), Value::String(s)) => {
634 (s.is_empty() && n.is_zero()) || n.to_string().eq(s)
635 }
636 (Value::String(s), Value::Number(n)) => {
637 (s.is_empty() && n.is_zero()) || n.to_string().eq(s)
638 }
639 (Value::String(s), v) => s.eq(v.to_string().as_str()),
640 (v, Value::String(s)) => s.eq(v.to_string().as_str()),
641 (Value::List(a), Value::Map(b)) => a.is_empty() && b.is_empty(),
642 (Value::Map(a), Value::List(b)) => a.is_empty() && b.is_empty(),
643 (_, _) => false,
644 }
645 }
646}
647
648#[cfg(test)]
649pub mod value_tests {
650 use crate::{Number, Value};
651 use wasm_bindgen_test::*;
652
653 #[wasm_bindgen_test(unsupported = test)]
654 fn value_eq() {
655 assert_eq!(Value::None, Value::None);
656 assert_eq!(Value::None, Value::Bool(false));
657 assert_eq!(Value::None, Value::Number(Number::Int(0)));
658 assert_eq!(Value::None, Value::Number(Number::Float(0.0)));
659 assert_eq!(Value::None, Value::String(String::new()));
660 assert_eq!(Value::Bool(false), Value::String(String::new()));
661 assert_eq!(Value::Number(Number::Int(0)), Value::String(String::new()));
662 }
663}