1use std::cell::RefCell;
2
3struct MemoryHistoryState {
4 current: String,
5 history: Vec<String>,
6 future: Vec<String>,
7}
8
9pub struct MemoryHistory {
11 state: RefCell<MemoryHistoryState>,
12}
13
14impl Default for MemoryHistory {
15 fn default() -> Self {
16 Self::with_initial_path("/")
17 }
18}
19
20impl MemoryHistory {
21 pub fn with_initial_path(path: impl ToString) -> Self {
22 Self {
23 state: MemoryHistoryState{
24 current: path.to_string().parse().unwrap_or_else(|err| {
25 panic!("index route does not exist:\n{err}\n use MemoryHistory::with_initial_path to set a custom path")
26 }),
27 history: Vec::new(),
28 future: Vec::new(),
29 }.into(),
30 }
31 }
32}
33
34impl MemoryHistory {
35 pub fn current_route(&self) -> String {
36 self.state.borrow().current.clone()
37 }
38
39 pub fn can_go_back(&self) -> bool {
40 !self.state.borrow().history.is_empty()
41 }
42
43 pub fn go_back(&self) {
44 let mut write = self.state.borrow_mut();
45 if let Some(last) = write.history.pop() {
46 let old = std::mem::replace(&mut write.current, last);
47 write.future.push(old);
48 }
49 }
50
51 pub fn can_go_forward(&self) -> bool {
52 !self.state.borrow().future.is_empty()
53 }
54
55 pub fn go_forward(&self) {
56 let mut write = self.state.borrow_mut();
57 if let Some(next) = write.future.pop() {
58 let old = std::mem::replace(&mut write.current, next);
59 write.history.push(old);
60 }
61 }
62
63 pub fn push(&self, new: String) {
64 let mut write = self.state.borrow_mut();
65 if write.current == new {
67 return;
68 }
69 let old = std::mem::replace(&mut write.current, new);
70 write.history.push(old);
71 write.future.clear();
72 }
73
74 pub fn replace(&self, path: String) {
75 let mut write = self.state.borrow_mut();
76 write.current = path;
77 }
78}