Skip to main content

gluex_rcdb/
data.rs

1use chrono::{DateTime, Utc};
2
3use crate::models::ValueType;
4
5#[derive(Debug, Clone)]
6enum Repr {
7    Text(String),
8    Int(i64),
9    Float(f64),
10    Bool(bool),
11    Time(DateTime<Utc>),
12}
13
14/// Typed wrapper for an individual RCDB condition value.
15#[derive(Debug, Clone)]
16pub struct Value {
17    value_type: ValueType,
18    repr: Repr,
19}
20
21impl Value {
22    fn new(value_type: ValueType, repr: Repr) -> Self {
23        Self { value_type, repr }
24    }
25
26    pub(crate) fn text(value_type: ValueType, value: Option<String>) -> Self {
27        Value::new(value_type, Repr::Text(value.unwrap_or_default()))
28    }
29
30    pub(crate) fn int(value: i64) -> Self {
31        Value::new(ValueType::Int, Repr::Int(value))
32    }
33
34    pub(crate) fn float(value: f64) -> Self {
35        Value::new(ValueType::Float, Repr::Float(value))
36    }
37
38    pub(crate) fn bool(value: bool) -> Self {
39        Value::new(ValueType::Bool, Repr::Bool(value))
40    }
41
42    pub(crate) fn time(value: DateTime<Utc>) -> Self {
43        Value::new(ValueType::Time, Repr::Time(value))
44    }
45
46    /// Returns the declared RCDB type of the value.
47    #[must_use]
48    pub fn value_type(&self) -> ValueType {
49        self.value_type
50    }
51
52    /// Returns the inner string (string, json, or blob) value if available.
53    #[must_use]
54    pub fn as_string(&self) -> Option<&str> {
55        if self.value_type.is_textual() {
56            if let Repr::Text(text) = &self.repr {
57                return Some(text);
58            }
59        }
60        None
61    }
62
63    /// Returns the integer payload when the value type is `int`.
64    #[must_use]
65    pub fn as_int(&self) -> Option<i64> {
66        match &self.repr {
67            Repr::Int(value) if self.value_type == ValueType::Int => Some(*value),
68            _ => None,
69        }
70    }
71
72    /// Returns the floating point payload when the value type is `float`.
73    #[must_use]
74    pub fn as_float(&self) -> Option<f64> {
75        match &self.repr {
76            Repr::Float(value) if self.value_type == ValueType::Float => Some(*value),
77            _ => None,
78        }
79    }
80
81    /// Returns the boolean payload when the value type is `bool`.
82    #[must_use]
83    pub fn as_bool(&self) -> Option<bool> {
84        match &self.repr {
85            Repr::Bool(value) if self.value_type == ValueType::Bool => Some(*value),
86            _ => None,
87        }
88    }
89
90    /// Returns the timestamp payload when the value type is `time`.
91    #[must_use]
92    pub fn as_time(&self) -> Option<DateTime<Utc>> {
93        match &self.repr {
94            Repr::Time(value) if self.value_type == ValueType::Time => Some(*value),
95            _ => None,
96        }
97    }
98}