use_simulation_result/
lib.rs1#![forbid(unsafe_code)]
2#[derive(Debug, Clone, PartialEq)]
20pub struct SimulationResult {
21 pub values: Vec<f64>,
22 pub final_value: f64,
23 pub min_value: f64,
24 pub max_value: f64,
25 pub steps: usize,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum SimulationResultError {
30 EmptySeries,
31 NonFiniteValue,
32}
33
34impl SimulationResult {
35 pub fn mean(&self) -> f64 {
36 self.values.iter().sum::<f64>() / self.values.len() as f64
37 }
38
39 pub fn range(&self) -> f64 {
40 self.max_value - self.min_value
41 }
42}
43
44pub fn summarize(values: &[f64]) -> Result<SimulationResult, SimulationResultError> {
45 if values.is_empty() {
46 return Err(SimulationResultError::EmptySeries);
47 }
48
49 if values.iter().any(|value| !value.is_finite()) {
50 return Err(SimulationResultError::NonFiniteValue);
51 }
52
53 let mut min_value = values[0];
54 let mut max_value = values[0];
55 for value in values.iter().copied().skip(1) {
56 if value < min_value {
57 min_value = value;
58 }
59 if value > max_value {
60 max_value = value;
61 }
62 }
63
64 Ok(SimulationResult {
65 values: values.to_vec(),
66 final_value: *values.last().unwrap(),
67 min_value,
68 max_value,
69 steps: values.len() - 1,
70 })
71}
72
73#[cfg(test)]
74mod tests {
75 use super::{SimulationResultError, summarize};
76
77 #[test]
78 fn summarizes_finite_series() {
79 let result = summarize(&[1.0, 2.0, 1.5, 3.0]).unwrap();
80
81 assert_eq!(result.final_value, 3.0);
82 assert_eq!(result.min_value, 1.0);
83 assert_eq!(result.max_value, 3.0);
84 assert_eq!(result.steps, 3);
85 assert_eq!(result.mean(), 1.875);
86 assert_eq!(result.range(), 2.0);
87 }
88
89 #[test]
90 fn handles_single_value_series() {
91 let result = summarize(&[4.0]).unwrap();
92
93 assert_eq!(result.steps, 0);
94 assert_eq!(result.range(), 0.0);
95 assert_eq!(result.mean(), 4.0);
96 }
97
98 #[test]
99 fn rejects_invalid_series() {
100 assert_eq!(summarize(&[]), Err(SimulationResultError::EmptySeries));
101 assert_eq!(
102 summarize(&[1.0, f64::NAN]),
103 Err(SimulationResultError::NonFiniteValue)
104 );
105 }
106}