* Create a crate for constant serialization of config structs for manganis * use SerializeConst for the image asset builder * switch to a declarative macro for assets * clean up asset macro a bit * add serializable options for each asset type * serialize const vec * Add unique path formatting * implement the new manganis macro * optimize assets in the CLI * Fix clippy * Fix assets with dioxus formattable * reduce fuzzing test limits * use the new syntax in examples * fix formatting * Final doc and test pass on const-serialize * fix avif support * Fix manganis doc tests * cache asset optimization * Split out asset and bundled asset * make hash pointer width independent * remove const serialize cargo lock * Fix manganis macro docs * all tests passing * add constvec::is_empty method to fix clippy lint * remove nasm feature * simplify test_rsplit_once test so typos passes * fix range syntax for stable * revert example change from clippy fix * remove dioxus-static-site-generation workspace dependency * always accept unix paths * fix windows path seperator * fix folder asset hash * Optimize assets in a blocking task * Fix asset options docs * Document Asset and BundledAsset * move manganis back into it's own folder * simplify the linker macro a bit * add more docs to AssetParser expansion * fix manganis core doc test * add image format helpers * Fill in new cargo.tomls * fix folders with explicit options * Split by both unix and windows path separators and take the smallest one * fix string length * Fix base path on web and fullstack * Fix assets with base path * fix fullstack base route with trailing slash * fix clippy
122 lines
3.4 KiB
Rust
122 lines
3.4 KiB
Rust
use std::cell::RefCell;
|
|
|
|
use crate::History;
|
|
|
|
struct MemoryHistoryState {
|
|
current: String,
|
|
history: Vec<String>,
|
|
future: Vec<String>,
|
|
}
|
|
|
|
/// A [`History`] provider that stores all navigation information in memory.
|
|
pub struct MemoryHistory {
|
|
state: RefCell<MemoryHistoryState>,
|
|
base_path: Option<String>,
|
|
}
|
|
|
|
impl Default for MemoryHistory {
|
|
fn default() -> Self {
|
|
Self::with_initial_path("/")
|
|
}
|
|
}
|
|
|
|
impl MemoryHistory {
|
|
/// Create a [`MemoryHistory`] starting at `path`.
|
|
///
|
|
/// ```rust
|
|
/// # use dioxus_router::prelude::*;
|
|
/// # use dioxus::prelude::*;
|
|
/// # #[component]
|
|
/// # fn Index() -> Element { VNode::empty() }
|
|
/// # #[component]
|
|
/// # fn OtherPage() -> Element { VNode::empty() }
|
|
/// #[derive(Clone, Routable, Debug, PartialEq)]
|
|
/// enum Route {
|
|
/// #[route("/")]
|
|
/// Index {},
|
|
/// #[route("/some-other-page")]
|
|
/// OtherPage {},
|
|
/// }
|
|
///
|
|
/// let mut history = dioxus_history::MemoryHistory::with_initial_path(Route::Index {});
|
|
/// assert_eq!(history.current_route(), Route::Index {}.to_string());
|
|
/// assert_eq!(history.can_go_back(), false);
|
|
/// ```
|
|
pub fn with_initial_path(path: impl ToString) -> Self {
|
|
Self {
|
|
state: MemoryHistoryState{
|
|
current: path.to_string().parse().unwrap_or_else(|err| {
|
|
panic!("index route does not exist:\n{err}\n use MemoryHistory::with_initial_path to set a custom path")
|
|
}),
|
|
history: Vec::new(),
|
|
future: Vec::new(),
|
|
}.into(),
|
|
base_path: None,
|
|
}
|
|
}
|
|
|
|
/// Set the base path for the history. All routes will be prefixed with this path when rendered.
|
|
///
|
|
/// ```rust
|
|
/// # use dioxus_history::*;
|
|
/// let mut history = MemoryHistory::default().with_prefix("/my-app");
|
|
///
|
|
/// // The base path is set to "/my-app"
|
|
/// assert_eq!(history.current_prefix(), Some("/my-app".to_string()));
|
|
/// ```
|
|
pub fn with_prefix(mut self, prefix: impl ToString) -> Self {
|
|
self.base_path = Some(prefix.to_string());
|
|
self
|
|
}
|
|
}
|
|
|
|
impl History for MemoryHistory {
|
|
fn current_prefix(&self) -> Option<String> {
|
|
self.base_path.clone()
|
|
}
|
|
|
|
fn current_route(&self) -> String {
|
|
self.state.borrow().current.clone()
|
|
}
|
|
|
|
fn can_go_back(&self) -> bool {
|
|
!self.state.borrow().history.is_empty()
|
|
}
|
|
|
|
fn go_back(&self) {
|
|
let mut write = self.state.borrow_mut();
|
|
if let Some(last) = write.history.pop() {
|
|
let old = std::mem::replace(&mut write.current, last);
|
|
write.future.push(old);
|
|
}
|
|
}
|
|
|
|
fn can_go_forward(&self) -> bool {
|
|
!self.state.borrow().future.is_empty()
|
|
}
|
|
|
|
fn go_forward(&self) {
|
|
let mut write = self.state.borrow_mut();
|
|
if let Some(next) = write.future.pop() {
|
|
let old = std::mem::replace(&mut write.current, next);
|
|
write.history.push(old);
|
|
}
|
|
}
|
|
|
|
fn push(&self, new: String) {
|
|
let mut write = self.state.borrow_mut();
|
|
// don't push the same route twice
|
|
if write.current == new {
|
|
return;
|
|
}
|
|
let old = std::mem::replace(&mut write.current, new);
|
|
write.history.push(old);
|
|
write.future.clear();
|
|
}
|
|
|
|
fn replace(&self, path: String) {
|
|
let mut write = self.state.borrow_mut();
|
|
write.current = path;
|
|
}
|
|
}
|