freya_router/
memory.rs

1use std::cell::RefCell;
2
3struct MemoryHistoryState {
4    current: String,
5    history: Vec<String>,
6    future: Vec<String>,
7}
8
9/// A *+History** provider that stores all navigation information in memory.
10pub 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        // don't push the same route twice
66        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}