1#[derive(Debug, Clone, PartialEq)]
12pub struct Quantile(f64, String);
13
14impl Quantile {
15 pub fn new(quantile: f64) -> Quantile {
19 let clamped = quantile.max(0.0);
20 let clamped = clamped.min(1.0);
21 let display = clamped * 100.0;
22
23 let raw_label = format!("{}", clamped);
24 let label = match raw_label.as_str() {
25 "0" => "min".to_string(),
26 "1" => "max".to_string(),
27 _ => {
28 let raw = format!("p{}", display);
29 raw.replace('.', "")
30 }
31 };
32
33 Quantile(clamped, label)
34 }
35
36 pub fn label(&self) -> &str {
38 self.1.as_str()
39 }
40
41 pub fn value(&self) -> f64 {
43 self.0
44 }
45}
46
47pub fn parse_quantiles(quantiles: &[f64]) -> Vec<Quantile> {
49 quantiles.iter().map(|f| Quantile::new(*f)).collect()
50}
51
52#[cfg(test)]
53mod tests {
54 use super::{parse_quantiles, Quantile};
55
56 #[test]
57 fn test_quantiles() {
58 let min = Quantile::new(0.0);
59 assert_eq!(min.value(), 0.0);
60 assert_eq!(min.label(), "min");
61
62 let max = Quantile::new(1.0);
63 assert_eq!(max.value(), 1.0);
64 assert_eq!(max.label(), "max");
65
66 let p99 = Quantile::new(0.99);
67 assert_eq!(p99.value(), 0.99);
68 assert_eq!(p99.label(), "p99");
69
70 let p999 = Quantile::new(0.999);
71 assert_eq!(p999.value(), 0.999);
72 assert_eq!(p999.label(), "p999");
73
74 let p9999 = Quantile::new(0.9999);
75 assert_eq!(p9999.value(), 0.9999);
76 assert_eq!(p9999.label(), "p9999");
77
78 let under = Quantile::new(-1.0);
79 assert_eq!(under.value(), 0.0);
80 assert_eq!(under.label(), "min");
81
82 let over = Quantile::new(1.2);
83 assert_eq!(over.value(), 1.0);
84 assert_eq!(over.label(), "max");
85 }
86
87 #[test]
88 fn test_parse_quantiles() {
89 let empty = vec![];
90 let result = parse_quantiles(&empty);
91 assert_eq!(result.len(), 0);
92
93 let normal = vec![0.0, 0.5, 0.99, 0.999, 1.0];
94 let result = parse_quantiles(&normal);
95 assert_eq!(result.len(), 5);
96 assert_eq!(result[0], Quantile::new(0.0));
97 assert_eq!(result[1], Quantile::new(0.5));
98 assert_eq!(result[2], Quantile::new(0.99));
99 assert_eq!(result[3], Quantile::new(0.999));
100 assert_eq!(result[4], Quantile::new(1.0));
101 }
102}