message_history.rs

 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}