tytanic_filter/eval/
value.rs

1use super::Error;
2use super::Func;
3use super::Set;
4use crate::ast::Num;
5use crate::ast::Str;
6
7/// The value of a test set expression.
8#[derive(Debug, Clone)]
9pub enum Value<T> {
10    /// A test.
11    Test(T),
12
13    /// A test set.
14    Set(Set<T>),
15
16    /// A function.
17    Func(Func<T>),
18
19    /// An unsigned integer.
20    Num(Num),
21
22    /// A string.
23    Str(Str),
24}
25
26impl<T> Value<T> {
27    /// The type of this expression.
28    pub fn as_type(&self) -> Type {
29        match self {
30            Value::Test(_) => Type::Test,
31            Value::Set(_) => Type::Set,
32            Value::Func(_) => Type::Func,
33            Value::Num(_) => Type::Num,
34            Value::Str(_) => Type::Str,
35        }
36    }
37
38    /// Convert this value into a `T` or return an error.
39    pub fn expect_type<V: TryFromValue<T>>(self) -> Result<V, Error>
40    where
41        T: Clone,
42    {
43        V::try_from_value(self)
44    }
45}
46
47impl<T> From<Set<T>> for Value<T> {
48    fn from(value: Set<T>) -> Self {
49        Self::Set(value)
50    }
51}
52
53impl<T> From<Func<T>> for Value<T> {
54    fn from(value: Func<T>) -> Self {
55        Self::Func(value)
56    }
57}
58
59impl<T> From<Num> for Value<T> {
60    fn from(value: Num) -> Self {
61        Self::Num(value)
62    }
63}
64
65impl<T> From<Str> for Value<T> {
66    fn from(value: Str) -> Self {
67        Self::Str(value)
68    }
69}
70
71/// A trait for types which can be unwrapped from a [`Value`].
72pub trait TryFromValue<T>: Sized {
73    fn try_from_value(value: Value<T>) -> Result<Self, Error>;
74}
75
76/// The type of a value.
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
78pub enum Type {
79    /// A test.
80    Test,
81
82    /// A test set.
83    Set,
84
85    /// A function.
86    Func,
87
88    /// An unsigned integer.
89    Num,
90
91    /// A string.
92    Str,
93}
94
95impl Type {
96    /// The name of this type.
97    pub fn name(&self) -> &'static str {
98        match self {
99            Self::Test => "test",
100            Self::Set => "test set",
101            Self::Func => "function",
102            Self::Num => "number",
103            Self::Str => "string",
104        }
105    }
106}