dsfb_semiconductor/input/
alarm_stream.rs1#[cfg(not(feature = "std"))]
2use alloc::{string::String, vec::Vec};
3
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7pub struct AlarmSample {
8 pub timestamp: f64,
9 pub source: String,
10 pub active: bool,
11}
12
13#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
14pub struct AlarmStream {
15 samples: Vec<AlarmSample>,
16}
17
18impl AlarmStream {
19 pub fn new(mut samples: Vec<AlarmSample>) -> Self {
20 samples.sort_by(|left, right| {
21 left.timestamp
22 .total_cmp(&right.timestamp)
23 .then_with(|| left.source.cmp(&right.source))
24 });
25 Self { samples }
26 }
27
28 pub fn from_samples(samples: &[AlarmSample]) -> Self {
29 Self::new(samples.to_vec())
30 }
31
32 pub fn push_clone(&mut self, sample: &AlarmSample) {
33 self.samples.push(sample.clone());
34 self.samples.sort_by(|left, right| {
35 left.timestamp
36 .total_cmp(&right.timestamp)
37 .then_with(|| left.source.cmp(&right.source))
38 });
39 }
40
41 pub fn samples(&self) -> &[AlarmSample] {
42 &self.samples
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn alarm_stream_is_sorted_deterministically() {
52 let stream = AlarmStream::new(vec![
53 AlarmSample {
54 timestamp: 5.0,
55 source: "ewma".into(),
56 active: true,
57 },
58 AlarmSample {
59 timestamp: 1.0,
60 source: "threshold".into(),
61 active: false,
62 },
63 ]);
64 assert_eq!(stream.samples()[0].timestamp, 1.0);
65 assert_eq!(stream.samples()[1].timestamp, 5.0);
66 }
67}