it almost lives?

This commit is contained in:
Evan Almloff committed 2023-07-25 18:14:48 -07:00
1 parent d637ef187c
commit 5f0dd3af3e
43 files changed
+506 -244

No files matched your search

+141 -1
View File
@@ -10,7 +10,7 @@
//! 1) [`MemoryHistory`] for desktop/mobile/ssr platforms
//! 2) [`WebHistory`] for web platforms
use std::sync::Arc;
use std::{any::Any, fmt::Display, sync::Arc};
mod memory;
pub use memory::*;
@@ -277,3 +277,143 @@ pub trait HistoryProvider<R: Routable> {
#[allow(unused_variables)]
fn updater(&mut self, callback: Arc<dyn Fn() + Send + Sync>) {}
}
/// Something that can be displayed and is also an [`Any`]
pub trait AnyDisplay: Display + Any {
/// Get a reference to the inner [`Any`] object.
fn as_any(&self) -> &dyn Any;
}
impl dyn AnyDisplay {
/// Try to downcast the inner [`Any`] object to a concrete type.
pub fn downcast<T: Any + Clone>(self: Box<dyn AnyDisplay>) -> Option<T> {
self.as_any().downcast_ref::<T>().cloned()
}
}
impl<T: Display + Any> AnyDisplay for T {
fn as_any(&self) -> &dyn Any {
self
}
}
pub(crate) trait AnyHistoryProvider {
#[must_use]
fn parse_route(&self, route: &str) -> Result<Box<dyn Any>, String>;
#[must_use]
fn accepts_type_id(&self, type_id: &std::any::TypeId) -> bool;
#[must_use]
fn current_route(&self) -> Box<dyn AnyDisplay>;
#[must_use]
fn current_prefix(&self) -> Option<String> {
None
}
#[must_use]
fn can_go_back(&self) -> bool {
true
}
fn go_back(&mut self);
#[must_use]
fn can_go_forward(&self) -> bool {
true
}
fn go_forward(&mut self);
fn push(&mut self, route: Box<dyn Any>);
fn replace(&mut self, path: Box<dyn Any>);
#[allow(unused_variables)]
fn external(&mut self, url: String) -> bool {
false
}
#[allow(unused_variables)]
fn updater(&mut self, callback: Arc<dyn Fn() + Send + Sync>) {}
}
pub(crate) struct AnyHistoryProviderImplWrapper<R, H> {
inner: H,
_marker: std::marker::PhantomData<R>,
}
impl<R, H> AnyHistoryProviderImplWrapper<R, H> {
pub fn new(inner: H) -> Self {
Self {
inner,
_marker: std::marker::PhantomData,
}
}
}
impl<R, H: Default> Default for AnyHistoryProviderImplWrapper<R, H> {
fn default() -> Self {
Self::new(H::default())
}
}
impl<R, H> AnyHistoryProvider for AnyHistoryProviderImplWrapper<R, H>
where
R: Routable,
<R as std::str::FromStr>::Err: std::fmt::Display,
H: HistoryProvider<R>,
{
fn parse_route(&self, route: &str) -> Result<Box<dyn Any>, String> {
R::from_str(route)
.map_err(|err| err.to_string())
.map(|route| Box::new(route) as Box<dyn Any>)
}
fn accepts_type_id(&self, type_id: &std::any::TypeId) -> bool {
type_id == &std::any::TypeId::of::<R>()
}
fn current_route(&self) -> Box<dyn AnyDisplay> {
let route = self.inner.current_route();
println!("current_route {route}");
Box::new(route)
}
fn current_prefix(&self) -> Option<String> {
self.inner.current_prefix()
}
fn can_go_back(&self) -> bool {
self.inner.can_go_back()
}
fn go_back(&mut self) {
self.inner.go_back()
}
fn can_go_forward(&self) -> bool {
self.inner.can_go_forward()
}
fn go_forward(&mut self) {
self.inner.go_forward()
}
fn push(&mut self, route: Box<dyn Any>) {
self.inner.push(*route.downcast().unwrap())
}
fn replace(&mut self, path: Box<dyn Any>) {
self.inner.replace(*path.downcast().unwrap())
}
fn external(&mut self, url: String) -> bool {
self.inner.external(url)
}
fn updater(&mut self, callback: Arc<dyn Fn() + Send + Sync>) {
self.inner.updater(callback)
}
}