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
102 lines
3.1 KiB
Rust
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())
|
|
}
|
|
}
|