Files
dioxus/packages/history/src/memory.rs
T
Evan Almloff 3d62fbf021 Fix base path on web and fullstack (#3247)
* 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
2024-11-27 10:40:55 +03:00

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;
}
}