vortex_scalar/
bool.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use vortex_dtype::Nullability::NonNullable;
use vortex_dtype::{DType, Nullability};
use vortex_error::{vortex_bail, vortex_err, VortexError, VortexResult};

use crate::value::ScalarValue;
use crate::Scalar;

pub struct BoolScalar<'a> {
    dtype: &'a DType,
    value: Option<bool>,
}

impl<'a> BoolScalar<'a> {
    #[inline]
    pub fn dtype(&self) -> &'a DType {
        self.dtype
    }

    pub fn value(&self) -> Option<bool> {
        self.value
    }

    pub fn cast(&self, dtype: &DType) -> VortexResult<Scalar> {
        match dtype {
            DType::Bool(_) => Ok(Scalar::bool(
                self.value().ok_or_else(|| vortex_err!("not a bool"))?,
                dtype.nullability(),
            )),
            _ => vortex_bail!("Can't cast {} to bool", dtype),
        }
    }
}

impl Scalar {
    pub fn bool(value: bool, nullability: Nullability) -> Self {
        Self {
            dtype: DType::Bool(nullability),
            value: ScalarValue::Bool(value),
        }
    }
}

impl<'a> TryFrom<&'a Scalar> for BoolScalar<'a> {
    type Error = VortexError;

    fn try_from(value: &'a Scalar) -> Result<Self, Self::Error> {
        if !matches!(value.dtype(), DType::Bool(_)) {
            vortex_bail!("Expected bool scalar, found {}", value.dtype())
        }
        Ok(Self {
            dtype: value.dtype(),
            value: value.value.as_bool()?,
        })
    }
}

impl TryFrom<&Scalar> for bool {
    type Error = VortexError;

    fn try_from(value: &Scalar) -> VortexResult<Self> {
        BoolScalar::try_from(value)?
            .value()
            .ok_or_else(|| vortex_err!("Can't extract present value from null scalar"))
    }
}

impl From<bool> for Scalar {
    fn from(value: bool) -> Self {
        Self {
            dtype: DType::Bool(NonNullable),
            value: value.into(),
        }
    }
}

impl TryFrom<&ScalarValue> for bool {
    type Error = VortexError;

    fn try_from(value: &ScalarValue) -> VortexResult<Self> {
        value
            .as_bool()?
            .ok_or_else(|| vortex_err!("Can't extract present value from null scalar"))
    }
}

impl From<bool> for ScalarValue {
    fn from(value: bool) -> Self {
        ScalarValue::Bool(value)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn into_from() {
        let scalar: Scalar = false.into();
        assert!(!bool::try_from(&scalar).unwrap());
    }
}