1#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5pub enum Navigation {
6 #[default]
8 Forward,
9 Back,
11}
12
13#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct Router<P> {
19 stack: Vec<P>,
20 direction: Navigation,
21}
22
23impl<P: Clone + PartialEq> Router<P> {
24 #[must_use]
26 pub fn new(root: P) -> Self {
27 Self { stack: vec![root], direction: Navigation::Forward }
28 }
29
30 #[must_use]
32 pub fn current(&self) -> &P {
33 self.stack.last().expect("the stack always holds the root page")
34 }
35
36 pub fn push(&mut self, page: P) {
38 if *self.current() != page {
39 self.stack.push(page);
40 self.direction = Navigation::Forward;
41 }
42 }
43
44 pub fn back(&mut self) -> bool {
46 if self.stack.len() > 1 {
47 self.stack.pop();
48 self.direction = Navigation::Back;
49 true
50 } else {
51 false
52 }
53 }
54
55 pub fn replace(&mut self, page: P) {
57 if let Some(top) = self.stack.last_mut() {
58 *top = page;
59 self.direction = Navigation::Forward;
60 }
61 }
62
63 #[must_use]
65 pub fn can_go_back(&self) -> bool {
66 self.stack.len() > 1
67 }
68
69 #[must_use]
71 pub fn direction(&self) -> Navigation {
72 self.direction
73 }
74
75 #[must_use]
77 pub fn history(&self) -> &[P] {
78 &self.stack
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn push_back_and_replace() {
88 let mut router = Router::new("home");
89 router.push("button");
90 router.push("button");
91 router.push("list");
92 assert_eq!(router.history(), &["home", "button", "list"]);
93 assert_eq!(router.direction(), Navigation::Forward);
94 assert!(router.back());
95 assert_eq!(router.direction(), Navigation::Back);
96 assert_eq!(*router.current(), "button");
97 router.replace("tabs");
98 assert_eq!(router.history(), &["home", "tabs"]);
99 assert!(router.back());
100 assert!(!router.back());
101 assert!(!router.can_go_back());
102 }
103}