rigz_vm/value/
bitor.rs

1use crate::value::Value;
2use crate::VMError;
3use std::ops::BitOr;
4
5impl BitOr for &Value {
6    type Output = Value;
7
8    #[inline]
9    fn bitor(self, rhs: Self) -> Self::Output {
10        match (self, rhs) {
11            (Value::Error(v), _) | (_, Value::Error(v)) => Value::Error(v.clone()),
12            (Value::Type(t), a) | (a, Value::Type(t)) => Value::Error(
13                VMError::UnsupportedOperation(format!("Invalid Operation (|): {t} and {a}")),
14            ),
15            (Value::None, rhs) => rhs.clone(),
16            (lhs, Value::None) => lhs.clone(),
17            (Value::Bool(a), Value::Bool(b)) => Value::Bool(a | b),
18            (Value::Bool(a), b) => Value::Bool(a | b.to_bool()),
19            (b, Value::Bool(a)) => Value::Bool(a | b.to_bool()),
20            (Value::Number(a), Value::Number(b)) => Value::Number(a | b),
21            (Value::Number(a), Value::String(b)) => {
22                let s = Value::String(b.clone());
23                match s.to_number() {
24                    Err(_) => VMError::UnsupportedOperation(format!("{} | {}", a, b)).to_value(),
25                    Ok(r) => Value::Number(a | &r),
26                }
27            }
28            (Value::Tuple(a), Value::Tuple(b)) => {
29                Value::Tuple(a.iter().zip(b).map(|(a, b)| a | b).collect())
30            }
31            (Value::Tuple(a), b) => Value::Tuple(a.iter().map(|a| a | b).collect()),
32            (b, Value::Tuple(a)) => Value::Tuple(a.iter().map(|a| b | a).collect()),
33            (lhs, rhs) => {
34                VMError::UnsupportedOperation(format!("Not supported: {lhs} | {rhs}")).into()
35            }
36        }
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use crate::define_value_tests;
43
44    define_value_tests! {
45        | {
46            test_none_bitor_none => ((), ()) = ();
47            test_none_bool_false_bitor_none => (false, ()) = false;
48            test_bool_true_bitor_none => (true, ()) = true;
49            test_none_bool_true_bitor_true => ((), true) = true;
50            test_false_bool_true_bitor_true => (false, true) = true;
51            test_false_0_bitor_true => (false, 0) = false;
52            test_true_0_bitor_true => (true, 0) = 1;
53        }
54    }
55}