This commit is contained in:
Hugh Kaznowski
2026-09-05 12:23:46 +01:00
parent 818f8d09ea
commit 68548911bc
34 changed files with 3262 additions and 4 deletions
+82
View File
@@ -0,0 +1,82 @@
use crate::timestamp::Timestamp;
use serde::Serialize;
use std::cmp::Ordering;
/// A simple, self-describing value used by metrics/labels without pulling in JSON.
#[allow(dead_code)]
#[derive(Debug, Clone, Serialize)]
pub enum MetricPrimitive {
String(String),
Number(Number),
Timestamp(Timestamp),
}
impl PartialEq for MetricPrimitive {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl Eq for MetricPrimitive {}
impl PartialOrd for MetricPrimitive {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for MetricPrimitive {
fn cmp(&self, other: &Self) -> Ordering {
fn rank(v: &MetricPrimitive) -> u8 {
match v {
MetricPrimitive::String(_) => 0,
MetricPrimitive::Number(_) => 1,
MetricPrimitive::Timestamp(_) => 2,
}
}
match (self, other) {
(MetricPrimitive::String(a), MetricPrimitive::String(b)) => a.cmp(b),
(MetricPrimitive::Number(a), MetricPrimitive::Number(b)) => a.cmp(b),
(MetricPrimitive::Timestamp(a), MetricPrimitive::Timestamp(b)) => a.cmp(b),
(a, b) => rank(a).cmp(&rank(b)),
}
}
}
/// Numbers are kept as a tagged int/float pair so exact integers stay exact.
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, Serialize)]
pub enum Number {
Int(i64),
Float(f64),
}
impl Number {
fn as_f64(&self) -> f64 {
match self {
Number::Int(v) => *v as f64,
Number::Float(v) => *v,
}
}
}
impl PartialEq for Number {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl Eq for Number {}
impl PartialOrd for Number {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Number {
fn cmp(&self, other: &Self) -> Ordering {
if let (Number::Int(a), Number::Int(b)) = (self, other) {
return a.cmp(b);
}
self.as_f64().total_cmp(&other.as_f64())
}
}