compose_library/foundations/ops/
equality.rs1use crate::diag::StrResult;
2use crate::{Array, ArrayValue, MapValue, Value};
3use compose_library::Heap;
4use compose_library::diag::bail;
5
6pub trait Comparison {
7 fn equals(&self, other: &Self, heap: &crate::Heap) -> compose_library::diag::StrResult<bool>;
8
9 fn not_equals(&self, other: &Self, heap: &Heap) -> StrResult<bool> {
10 self.equals(other, heap).map(|b| !b)
11 }
12}
13
14impl Comparison for Value {
15 fn equals(&self, other: &Value, heap: &Heap) -> StrResult<bool> {
16 match (self, other) {
17 (Value::Int(left), Value::Int(right)) => Ok(left == right),
18 (Value::Bool(left), Value::Bool(right)) => Ok(left == right),
19 (Value::Str(left), Value::Str(right)) => Ok(left == right),
20 (Value::Func(left), Value::Func(right)) => Ok(left == right),
21 (Value::Type(left), Value::Type(right)) => Ok(left == right),
22 (Value::Iterator(_left), Value::Iterator(_right)) => {
23 bail!("cannot compare iterators for equality")
24 }
25 (Value::Unit(_), Value::Unit(_)) => Ok(true),
26 (Value::Box(left), Value::Box(right)) => Ok(left == right),
28 (Value::Range(left), Value::Range(right)) => Ok(left == right),
29 (Value::Array(left), Value::Array(right)) => left.equals(right, heap),
30 (Value::Map(left), Value::Map(right)) => left.equals(right, heap),
31 (Value::Module(left), Value::Module(right)) => Ok(left == right),
32
33 (Value::Range(_), _)
37 | (Value::Func(_), _)
38 | (Value::Type(_), _)
39 | (Value::Unit(_), _)
40 | (Value::Str(_), _)
41 | (Value::Bool(_), _)
42 | (Value::Iterator(_), _)
43 | (Value::Box(_), _)
44 | (Value::Array(_), _)
45 | (Value::Map(_), _)
46 | (Value::Module(_), _)
47 | (Value::Int(_), _) => Ok(false),
48 }
49 }
50}
51
52impl Comparison for ArrayValue {
53 fn equals(&self, other: &Self, heap: &Heap) -> StrResult<bool> {
54 let left = self.heap_ref().get_unwrap(heap);
55 let right = other.heap_ref().get_unwrap(heap);
56
57 left.equals(right, heap)
58 }
59}
60
61impl Comparison for Array {
62 fn equals(&self, other: &Self, heap: &Heap) -> StrResult<bool> {
63 if self.values.len() != other.values.len() {
64 return Ok(false);
65 }
66
67 for (a, b) in self.values.iter().zip(&other.values) {
68 if !a.equals(b, heap)? {
69 return Ok(false);
70 }
71 }
72
73 Ok(true)
74 }
75}
76
77impl Comparison for MapValue {
78 fn equals(&self, other: &Self, heap: &Heap) -> StrResult<bool> {
79 let left = self.heap_ref().get_unwrap(heap);
80 let right = other.heap_ref().get_unwrap(heap);
81
82 left.equals(right, heap)
83 }
84}