1use std::time;
2use std::{fmt, iter::DoubleEndedIterator, mem, vec::Vec};
3
4pub struct HistoryBuffer<T> {
9 max_size: usize,
10 write_index: usize,
11 buffer: Vec<T>,
12 last_data_at: time::Instant,
13}
14
15impl<T> HistoryBuffer<T> {
16 pub fn new(max_size: usize) -> Self {
18 HistoryBuffer {
19 max_size,
20 write_index: 0,
21 buffer: Vec::with_capacity(max_size),
22 last_data_at: time::Instant::now(),
23 }
24 }
25
26 pub fn is_empty(&self) -> bool {
28 self.buffer.len() == 0
29 }
30
31 pub fn is_full(&self) -> bool {
33 self.buffer.len() == self.max_size
34 }
35
36 pub fn max_len(&self) -> usize {
38 self.max_size
39 }
40
41 pub fn len(&self) -> usize {
43 self.buffer.len()
44 }
45
46 pub fn clear(&mut self) {
48 self.write_index = 0;
49 self.buffer.clear();
50 }
51
52 pub fn most_recent(&self) -> Option<&T> {
54 if self.is_empty() {
55 None
56 } else {
57 if self.write_index == 0 {
58 self.buffer.last()
59 } else {
60 Some(&self.buffer[self.write_index - 1])
61 }
62 }
63 }
64
65 pub fn write(&mut self, val: T) -> Option<T> {
67 let r = if self.is_full() {
68 Some(mem::replace(&mut self.buffer[self.write_index], val))
69 } else {
70 self.buffer.push(val);
71
72 None
73 };
74
75 self.write_index = (self.write_index.wrapping_add(1)) % self.max_size;
76 self.last_data_at = time::Instant::now();
77
78 r
79 }
80
81 pub fn duration_since_last_measurement(&self) -> Option<time::Duration> {
83 if !self.is_empty() {
84 let now = time::Instant::now();
85 Some(now.duration_since(self.last_data_at))
86 } else {
87 None
88 }
89 }
90
91 pub fn all_unsorted(&self) -> &[T] {
93 &self.buffer
94 }
95
96 pub fn all(&self) -> impl DoubleEndedIterator<Item = &T> {
98 let write_index = self.write_index;
99 self.buffer[write_index..]
100 .iter()
101 .chain(self.buffer[..write_index].iter())
102 }
103}
104
105impl<T> fmt::Debug for HistoryBuffer<T>
106where
107 T: fmt::Debug,
108{
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
110 f.debug_list().entries(self.all()).finish()
111 }
112}