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#[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 #[must_use]
48 pub fn value_type(&self) -> ValueType {
49 self.value_type
50 }
51
52 #[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 #[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 #[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 #[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 #[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}