Skip to main content

gluex_rcdb/
models.rs

1use chrono::{DateTime, Utc};
2use gluex_core::{parsers::parse_timestamp, Id, RunNumber};
3
4use crate::RCDBResult;
5
6/// Typed representation of a condition value column.
7#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
8pub enum ValueType {
9    /// Human readable UTF-8 string payload.
10    #[default]
11    String,
12    /// Signed integer payload stored in `int_value` (i32).
13    Int,
14    /// Boolean payload stored in `bool_value`.
15    Bool,
16    /// Floating point payload stored in `float_value`.
17    Float,
18    /// JSON encoded blob stored in `text_value` (f64).
19    Json,
20    /// Arbitrary blob (stored as text) stored in `text_value`.
21    Blob,
22    /// Timestamp payload stored in `time_value`.
23    Time,
24}
25impl ValueType {
26    /// Returns the identifier string stored in the database.
27    #[must_use]
28    pub fn as_str(&self) -> &'static str {
29        match self {
30            ValueType::String => "string",
31            ValueType::Int => "int",
32            ValueType::Bool => "bool",
33            ValueType::Float => "float",
34            ValueType::Json => "json",
35            ValueType::Blob => "blob",
36            ValueType::Time => "time",
37        }
38    }
39
40    /// Builds a [`ValueType`] from the identifier stored in `SQLite`.
41    #[must_use]
42    pub fn from_identifier(value: &str) -> Option<Self> {
43        match value {
44            "string" => Some(ValueType::String),
45            "int" => Some(ValueType::Int),
46            "bool" => Some(ValueType::Bool),
47            "float" => Some(ValueType::Float),
48            "json" => Some(ValueType::Json),
49            "blob" => Some(ValueType::Blob),
50            "time" => Some(ValueType::Time),
51            _ => None,
52        }
53    }
54
55    /// True when the value is backed by the `text_value` column.
56    #[must_use]
57    pub fn is_textual(&self) -> bool {
58        matches!(self, ValueType::String | ValueType::Json | ValueType::Blob)
59    }
60
61    /// Returns the storage column name used in the `conditions` table.
62    #[must_use]
63    pub fn column_name(&self) -> &'static str {
64        match self {
65            ValueType::String | ValueType::Json | ValueType::Blob => "text_value",
66            ValueType::Int => "int_value",
67            ValueType::Bool => "bool_value",
68            ValueType::Float => "float_value",
69            ValueType::Time => "time_value",
70        }
71    }
72}
73/// Metadata record for a condition type entry.
74#[derive(Debug, Clone)]
75pub struct ConditionTypeMeta {
76    pub(crate) id: Id,
77    pub(crate) name: String,
78    pub(crate) value_type: ValueType,
79    pub(crate) created: String,
80    pub(crate) description: String,
81}
82impl ConditionTypeMeta {
83    /// Database identifier for the condition type.
84    #[must_use]
85    pub fn id(&self) -> Id {
86        self.id
87    }
88    /// Name of the condition type.
89    #[must_use]
90    pub fn name(&self) -> &str {
91        &self.name
92    }
93    /// [`ValueType`] used to store the condition.
94    #[must_use]
95    pub fn value_type(&self) -> ValueType {
96        self.value_type
97    }
98    /// Timestamp describing when the condition was created.
99    #[must_use]
100    pub fn created(&self) -> String {
101        self.created.clone()
102    }
103    /// Free-form description associated with the condition.
104    #[must_use]
105    pub fn description(&self) -> &str {
106        &self.description
107    }
108}
109
110/// Raw metadata row for an individual condition value.
111#[derive(Debug, Clone)]
112pub struct ConditionMeta {
113    pub(crate) id: Id,
114    pub(crate) text_value: String,
115    pub(crate) int_value: i64,
116    pub(crate) float_value: f64,
117    pub(crate) bool_value: i64,
118    pub(crate) run_number: RunNumber,
119    pub(crate) condition_type_id: Id,
120    pub(crate) created: String,
121    pub(crate) time_value: String,
122}
123impl ConditionMeta {
124    /// Identifier of the condition row.
125    #[must_use]
126    pub fn id(&self) -> Id {
127        self.id
128    }
129    /// Raw text value stored alongside the condition.
130    #[must_use]
131    pub fn text_value(&self) -> &str {
132        &self.text_value
133    }
134    /// Raw integer value stored alongside the condition.
135    #[must_use]
136    pub fn int_value(&self) -> i64 {
137        self.int_value
138    }
139    /// Raw floating-point value stored alongside the condition.
140    #[must_use]
141    pub fn float_value(&self) -> f64 {
142        self.float_value
143    }
144    /// Raw boolean stored as an integer (0 or 1).
145    #[must_use]
146    pub fn bool_value(&self) -> i64 {
147        self.bool_value
148    }
149    /// Run number associated with the condition.
150    #[must_use]
151    pub fn run_number(&self) -> i64 {
152        self.run_number
153    }
154    /// Identifier referencing the condition type entry.
155    #[must_use]
156    pub fn condition_type_id(&self) -> Id {
157        self.condition_type_id
158    }
159    /// Timestamp describing when the condition was created.
160    ///
161    /// # Errors
162    ///
163    /// Returns an error if the stored creation timestamp cannot be parsed as a UTC datetime.
164    pub fn created(&self) -> RCDBResult<DateTime<Utc>> {
165        Ok(parse_timestamp(&self.created)?)
166    }
167    /// Optional timestamp value associated with the condition.
168    ///
169    /// # Errors
170    ///
171    /// Returns an error if the stored timestamp cannot be parsed as a UTC datetime.
172    pub fn time_value(&self) -> RCDBResult<DateTime<Utc>> {
173        Ok(parse_timestamp(&self.time_value)?)
174    }
175}
176
177/// Metadata describing a named RCDB run period.
178#[derive(Debug, Clone)]
179pub struct RunPeriodMeta {
180    pub(crate) id: Id,
181    pub(crate) name: String,
182    pub(crate) description: String,
183    pub(crate) run_min: RunNumber,
184    pub(crate) run_max: RunNumber,
185    pub(crate) start_date: String,
186    pub(crate) end_date: String,
187}
188impl RunPeriodMeta {
189    /// Identifier of the run period.
190    #[must_use]
191    pub fn id(&self) -> Id {
192        self.id
193    }
194    /// Human-readable period name.
195    #[must_use]
196    pub fn name(&self) -> &str {
197        &self.name
198    }
199    /// Optional descriptive text for the run period.
200    #[must_use]
201    pub fn description(&self) -> &str {
202        &self.description
203    }
204    /// Minimum run number included in the period.
205    #[must_use]
206    pub fn run_min(&self) -> RunNumber {
207        self.run_min
208    }
209    /// Maximum run number included in the period.
210    #[must_use]
211    pub fn run_max(&self) -> RunNumber {
212        self.run_max
213    }
214    /// Timestamp describing when the period started.
215    ///
216    /// # Errors
217    ///
218    /// Returns an error if the stored start timestamp cannot be parsed as a UTC datetime.
219    pub fn start_date(&self) -> RCDBResult<DateTime<Utc>> {
220        Ok(parse_timestamp(&self.start_date)?)
221    }
222    /// Timestamp describing when the period ended.
223    ///
224    /// # Errors
225    ///
226    /// Returns an error if the stored end timestamp cannot be parsed as a UTC datetime.
227    pub fn end_date(&self) -> RCDBResult<DateTime<Utc>> {
228        Ok(parse_timestamp(&self.end_date)?)
229    }
230}
231
232/// Metadata describing a single run record.
233#[derive(Debug, Clone)]
234pub struct RunMeta {
235    pub(crate) number: RunNumber,
236    pub(crate) started: String,
237    pub(crate) finished: String,
238}
239impl RunMeta {
240    /// Run number for this record.
241    #[must_use]
242    pub fn number(&self) -> RunNumber {
243        self.number
244    }
245    /// Timestamp indicating when the run began.
246    ///
247    /// # Errors
248    ///
249    /// Returns an error if the stored run start timestamp cannot be parsed as a UTC datetime.
250    pub fn started(&self) -> RCDBResult<DateTime<Utc>> {
251        Ok(parse_timestamp(&self.started)?)
252    }
253    /// Timestamp indicating when the run finished.
254    ///
255    /// # Errors
256    ///
257    /// Returns an error if the stored run end timestamp cannot be parsed as a UTC datetime.
258    pub fn finished(&self) -> RCDBResult<DateTime<Utc>> {
259        Ok(parse_timestamp(&self.finished)?)
260    }
261}