partiql_value/value/
logic.rs

1use crate::Value;
2use std::ops;
3
4impl ops::Not for &Value {
5    type Output = Value;
6
7    fn not(self) -> Self::Output {
8        match self {
9            Value::Boolean(b) => Value::from(!b),
10            Value::Null | Value::Missing => Value::Null,
11            _ => Value::Missing, // data type mismatch => Missing
12        }
13    }
14}
15
16impl ops::Not for Value {
17    type Output = Self;
18
19    fn not(self) -> Self::Output {
20        match self {
21            Value::Boolean(b) => Value::from(!b),
22            Value::Null | Value::Missing => Value::Null,
23            _ => Value::Missing, // data type mismatch => Missing
24        }
25    }
26}
27
28pub trait BinaryAnd {
29    type Output;
30
31    fn and(&self, rhs: &Self) -> Self::Output;
32}
33
34impl BinaryAnd for Value {
35    type Output = Self;
36    fn and(&self, rhs: &Self) -> Self::Output {
37        match (self, rhs) {
38            (Value::Boolean(l), Value::Boolean(r)) => Value::from(*l && *r),
39            (Value::Null | Value::Missing, Value::Boolean(false))
40            | (Value::Boolean(false), Value::Null | Value::Missing) => Value::from(false),
41            _ => {
42                if matches!(self, Value::Missing | Value::Null | Value::Boolean(true))
43                    && matches!(rhs, Value::Missing | Value::Null | Value::Boolean(true))
44                {
45                    Value::Null
46                } else {
47                    Value::Missing
48                }
49            }
50        }
51    }
52}
53
54pub trait BinaryOr {
55    type Output;
56
57    fn or(&self, rhs: &Self) -> Self::Output;
58}
59
60impl BinaryOr for Value {
61    type Output = Self;
62    fn or(&self, rhs: &Self) -> Self::Output {
63        match (self, rhs) {
64            (Value::Boolean(l), Value::Boolean(r)) => Value::from(*l || *r),
65            (Value::Null | Value::Missing, Value::Boolean(true))
66            | (Value::Boolean(true), Value::Null | Value::Missing) => Value::from(true),
67            _ => {
68                if matches!(self, Value::Missing | Value::Null | Value::Boolean(false))
69                    && matches!(rhs, Value::Missing | Value::Null | Value::Boolean(false))
70                {
71                    Value::Null
72                } else {
73                    Value::Missing
74                }
75            }
76        }
77    }
78}