Files
ottyl/src/metric_primitive.rs
T
Hugh KaznowskiandClaude Sonnet 5 00c21c8032 Trim comments across Rust and webapp source to direct one-liners (ticket 030)
Pass over src/*.rs, webapp/src/**, and the in-app "?" docs prose:
condensed multi-paragraph doc comments to single lines that state the
non-obvious why, deleted comments that only restated adjacent code, and
tightened the Docs.tsx help-panel wording. No logic, structure, or code
formatting changed — verified via cargo test (143 passed) and
tsc -b && vite build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
2026-09-05 17:02:33 +01:00

102 lines
3.1 KiB
Rust

use crate::timestamp::Timestamp;
use serde::Serialize;
use std::cmp::Ordering;
use std::fmt;
/// 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),
/// Milliseconds elapsed; distinct from `Number` so it reads unambiguously in JSON/label form.
Duration(i64),
}
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,
MetricPrimitive::Duration(_) => 3,
}
}
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),
(MetricPrimitive::Duration(a), MetricPrimitive::Duration(b)) => a.cmp(b),
(a, b) => rank(a).cmp(&rank(b)),
}
}
}
/// Textual form used to compare label filters (query-string values) against a formatted `MetricPrimitive` rather than parsing them into one.
impl fmt::Display for MetricPrimitive {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MetricPrimitive::String(s) => write!(f, "{s}"),
MetricPrimitive::Number(Number::Int(n)) => write!(f, "{n}"),
MetricPrimitive::Number(Number::Float(n)) => write!(f, "{n}"),
MetricPrimitive::Timestamp(ts) => write!(f, "{}", ts.as_millis()),
MetricPrimitive::Duration(ms) => write!(f, "{ms}"),
}
}
}
/// 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 {
/// Widens to `f64` for cross-kind numeric comparisons; `pub(crate)` since the filter evaluator in `engine.rs` needs it.
pub(crate) 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())
}
}