trueno_db/experiment/
metric_record.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
18pub struct MetricRecord {
19 run_id: String,
20 key: String,
21 step: u64,
22 value: f64,
23 timestamp: DateTime<Utc>,
24}
25
26impl MetricRecord {
27 #[must_use]
40 pub fn new(run_id: impl Into<String>, key: impl Into<String>, step: u64, value: f64) -> Self {
41 Self { run_id: run_id.into(), key: key.into(), step, value, timestamp: Utc::now() }
42 }
43
44 #[must_use]
46 pub fn builder(
47 run_id: impl Into<String>,
48 key: impl Into<String>,
49 step: u64,
50 value: f64,
51 ) -> MetricRecordBuilder {
52 MetricRecordBuilder::new(run_id, key, step, value)
53 }
54
55 #[must_use]
57 pub fn run_id(&self) -> &str {
58 &self.run_id
59 }
60
61 #[must_use]
63 pub fn key(&self) -> &str {
64 &self.key
65 }
66
67 #[must_use]
69 pub const fn step(&self) -> u64 {
70 self.step
71 }
72
73 #[must_use]
75 pub const fn value(&self) -> f64 {
76 self.value
77 }
78
79 #[must_use]
81 pub const fn timestamp(&self) -> DateTime<Utc> {
82 self.timestamp
83 }
84}
85
86#[derive(Debug)]
88pub struct MetricRecordBuilder {
89 run_id: String,
90 key: String,
91 step: u64,
92 value: f64,
93 timestamp: DateTime<Utc>,
94}
95
96impl MetricRecordBuilder {
97 #[must_use]
99 pub fn new(run_id: impl Into<String>, key: impl Into<String>, step: u64, value: f64) -> Self {
100 Self { run_id: run_id.into(), key: key.into(), step, value, timestamp: Utc::now() }
101 }
102
103 #[must_use]
105 pub const fn timestamp(mut self, timestamp: DateTime<Utc>) -> Self {
106 self.timestamp = timestamp;
107 self
108 }
109
110 #[must_use]
112 pub fn build(self) -> MetricRecord {
113 MetricRecord {
114 run_id: self.run_id,
115 key: self.key,
116 step: self.step,
117 value: self.value,
118 timestamp: self.timestamp,
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_metric_record_new() {
129 let metric = MetricRecord::new("run-1", "loss", 0, 0.5);
130 assert_eq!(metric.run_id(), "run-1");
131 assert_eq!(metric.key(), "loss");
132 assert_eq!(metric.step(), 0);
133 assert!((metric.value() - 0.5).abs() < f64::EPSILON);
134 }
135
136 #[test]
137 fn test_metric_record_ordering() {
138 let m1 = MetricRecord::new("run-1", "loss", 0, 1.0);
139 let m2 = MetricRecord::new("run-1", "loss", 1, 0.9);
140 assert!(m1.step() < m2.step());
141 }
142}