Skip to main content

hippmem_core/
score.rs

1//! Bounded score UnitScore: 0.0..=1.0, clamped at construction. See 02#0.
2
3use serde::{Deserialize, Serialize};
4
5/// Bounded score in 0.0..=1.0 (strength/confidence/importance).
6///
7/// **Invariant**: the inner f32 is always within `[0.0, 1.0]`.
8/// `UnitScore::new(x)` clamps out-of-range values and maps NaN to zero.
9#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
10pub struct UnitScore(f32);
11
12impl UnitScore {
13    /// Constructs a UnitScore, automatically clamped to [0.0, 1.0]. NaN maps to zero.
14    pub fn new(value: f32) -> Self {
15        if value.is_nan() {
16            Self(0.0)
17        } else {
18            Self(value.clamp(0.0, 1.0))
19        }
20    }
21
22    /// Returns the inner f32 value (always in [0.0, 1.0]).
23    pub fn value(&self) -> f32 {
24        self.0
25    }
26}
27
28impl Default for UnitScore {
29    fn default() -> Self {
30        Self(0.5)
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn default_is_midpoint() {
40        assert!((UnitScore::default().value() - 0.5).abs() < f32::EPSILON);
41    }
42}