123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- use std::str::FromStr;
- use crate::routable::Routable;
- use super::HistoryProvider;
- /// A [`HistoryProvider`] that stores all navigation information in memory.
- pub struct MemoryHistory<R: Routable> {
- current: R,
- history: Vec<R>,
- future: Vec<R>,
- }
- impl<R: Routable> MemoryHistory<R>
- where
- <R as FromStr>::Err: std::fmt::Display,
- {
- /// Create a [`MemoryHistory`] starting at `path`.
- ///
- /// ```rust
- /// # use dioxus_router_core::history::{HistoryProvider, MemoryHistory};
- /// let mut history = MemoryHistory::with_initial_path("/some/path").unwrap();
- /// assert_eq!(history.current_path(), "/some/path");
- /// assert_eq!(history.can_go_back(), false);
- /// ```
- pub fn with_initial_path(path: impl Into<String>) -> Result<Self, <R as FromStr>::Err> {
- let path = path.into();
- Ok(Self {
- current: R::from_str(&path)?,
- ..Default::default()
- })
- }
- }
- impl<R: Routable> Default for MemoryHistory<R>
- where
- <R as FromStr>::Err: std::fmt::Display,
- {
- fn default() -> Self {
- Self {
- current: "/".parse().unwrap_or_else(|err| panic!("{}", err)),
- history: Vec::new(),
- future: Vec::new(),
- }
- }
- }
- impl<R: Routable> HistoryProvider<R> for MemoryHistory<R> {
- fn current_route(&self) -> R {
- self.current.clone()
- }
- fn can_go_back(&self) -> bool {
- !self.history.is_empty()
- }
- fn go_back(&mut self) {
- if let Some(last) = self.history.pop() {
- let old = std::mem::replace(&mut self.current, last);
- self.future.push(old);
- }
- }
- fn can_go_forward(&self) -> bool {
- !self.future.is_empty()
- }
- fn go_forward(&mut self) {
- if let Some(next) = self.future.pop() {
- let old = std::mem::replace(&mut self.current, next);
- self.history.push(old);
- }
- }
- fn push(&mut self, new: R) {
- let old = std::mem::replace(&mut self.current, new);
- self.history.push(old);
- self.future.clear();
- }
- fn replace(&mut self, path: R) {
- self.current = path;
- }
- }
- // #[cfg(test)]
- // mod tests {
- // use super::*;
- // #[test]
- // fn default() {
- // let mem = MemoryHistory::default();
- // assert_eq!(mem.current, Url::parse(INITIAL_URL).unwrap());
- // assert_eq!(mem.history, Vec::<String>::new());
- // assert_eq!(mem.future, Vec::<String>::new());
- // }
- // #[test]
- // fn with_initial_path() {
- // let mem = MemoryHistory::with_initial_path("something").unwrap();
- // assert_eq!(
- // mem.current,
- // Url::parse(&format!("{INITIAL_URL}something")).unwrap()
- // );
- // assert_eq!(mem.history, Vec::<String>::new());
- // assert_eq!(mem.future, Vec::<String>::new());
- // }
- // #[test]
- // fn with_initial_path_with_leading_slash() {
- // let mem = MemoryHistory::with_initial_path("/something").unwrap();
- // assert_eq!(
- // mem.current,
- // Url::parse(&format!("{INITIAL_URL}something")).unwrap()
- // );
- // assert_eq!(mem.history, Vec::<String>::new());
- // assert_eq!(mem.future, Vec::<String>::new());
- // }
- // #[test]
- // fn can_go_back() {
- // let mut mem = MemoryHistory::default();
- // assert!(!mem.can_go_back());
- // mem.push(String::from("/test"));
- // assert!(mem.can_go_back());
- // }
- // #[test]
- // fn go_back() {
- // let mut mem = MemoryHistory::default();
- // mem.push(String::from("/test"));
- // mem.go_back();
- // assert_eq!(mem.current, Url::parse(INITIAL_URL).unwrap());
- // assert!(mem.history.is_empty());
- // assert_eq!(mem.future, vec![format!("{INITIAL_URL}test")]);
- // }
- // #[test]
- // fn can_go_forward() {
- // let mut mem = MemoryHistory::default();
- // assert!(!mem.can_go_forward());
- // mem.push(String::from("/test"));
- // mem.go_back();
- // assert!(mem.can_go_forward());
- // }
- // #[test]
- // fn go_forward() {
- // let mut mem = MemoryHistory::default();
- // mem.push(String::from("/test"));
- // mem.go_back();
- // mem.go_forward();
- // assert_eq!(
- // mem.current,
- // Url::parse(&format!("{INITIAL_URL}test")).unwrap()
- // );
- // assert_eq!(mem.history, vec![INITIAL_URL.to_string()]);
- // assert!(mem.future.is_empty());
- // }
- // #[test]
- // fn push() {
- // let mut mem = MemoryHistory::default();
- // mem.push(String::from("/test"));
- // assert_eq!(
- // mem.current,
- // Url::parse(&format!("{INITIAL_URL}test")).unwrap()
- // );
- // assert_eq!(mem.history, vec![INITIAL_URL.to_string()]);
- // assert!(mem.future.is_empty());
- // }
- // #[test]
- // #[should_panic = r#"cannot navigate to paths starting with "//": //test"#]
- // #[cfg(debug_assertions)]
- // fn push_debug() {
- // let mut mem = MemoryHistory::default();
- // mem.push(String::from("//test"));
- // }
- // #[test]
- // #[cfg(not(debug_assertions))]
- // fn push_release() {
- // let mut mem = MemoryHistory::default();
- // mem.push(String::from("//test"));
- // assert_eq!(mem.current, Url::parse(INITIAL_URL).unwrap());
- // assert!(mem.history.is_empty())
- // }
- // #[test]
- // fn replace() {
- // let mut mem = MemoryHistory::default();
- // mem.push(String::from("/test"));
- // mem.push(String::from("/other"));
- // mem.go_back();
- // mem.replace(String::from("/replace"));
- // assert_eq!(
- // mem.current,
- // Url::parse(&format!("{INITIAL_URL}replace")).unwrap()
- // );
- // assert_eq!(mem.history, vec![INITIAL_URL.to_string()]);
- // assert_eq!(mem.future, vec![format!("{INITIAL_URL}other")]);
- // }
- // #[test]
- // #[should_panic = r#"cannot navigate to paths starting with "//": //test"#]
- // #[cfg(debug_assertions)]
- // fn replace_debug() {
- // let mut mem = MemoryHistory::default();
- // mem.replace(String::from("//test"));
- // }
- // #[test]
- // #[cfg(not(debug_assertions))]
- // fn replace_release() {
- // let mut mem = MemoryHistory::default();
- // mem.replace(String::from("//test"));
- // assert_eq!(mem.current, Url::parse(INITIAL_URL).unwrap());
- // }
- // }
|