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