1pub struct MessageHistory<T> {
2 items: Vec<T>,
3 current: Option<usize>,
4}
5
6impl<T> MessageHistory<T> {
7 pub fn new() -> Self {
8 MessageHistory {
9 items: Vec::new(),
10 current: None,
11 }
12 }
13
14 pub fn push(&mut self, message: T) {
15 self.current.take();
16 self.items.push(message);
17 }
18
19 pub fn prev(&mut self) -> Option<&T> {
20 if self.items.is_empty() {
21 return None;
22 }
23
24 let new_ix = self
25 .current
26 .get_or_insert(self.items.len())
27 .saturating_sub(1);
28
29 self.current = Some(new_ix);
30 self.items.get(new_ix)
31 }
32
33 pub fn next(&mut self) -> Option<&T> {
34 let current = self.current.as_mut()?;
35 *current += 1;
36
37 self.items.get(*current).or_else(|| {
38 self.current.take();
39 None
40 })
41 }
42}
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_prev_next() {
49 let mut history = MessageHistory::new();
50
51 // Test empty history
52 assert_eq!(history.prev(), None);
53 assert_eq!(history.next(), None);
54
55 // Add some messages
56 history.push("first");
57 history.push("second");
58 history.push("third");
59
60 // Test prev navigation
61 assert_eq!(history.prev(), Some(&"third"));
62 assert_eq!(history.prev(), Some(&"second"));
63 assert_eq!(history.prev(), Some(&"first"));
64 assert_eq!(history.prev(), Some(&"first"));
65
66 assert_eq!(history.next(), Some(&"second"));
67
68 // Test mixed navigation
69 history.push("fourth");
70 assert_eq!(history.prev(), Some(&"fourth"));
71 assert_eq!(history.prev(), Some(&"third"));
72 assert_eq!(history.next(), Some(&"fourth"));
73 assert_eq!(history.next(), None);
74
75 // Test that push resets navigation
76 history.prev();
77 history.prev();
78 history.push("fifth");
79 assert_eq!(history.prev(), Some(&"fifth"));
80 }
81}