use dioxus_lib::prelude::*; use std::{cell::RefCell, str::FromStr}; use crate::{prelude::Outlet, routable::Routable, router_cfg::RouterConfig}; /// The config for [`Router`]. pub struct RouterConfigFactory { #[allow(clippy::type_complexity)] config: RefCell RouterConfig>>>, } #[cfg(feature = "serde")] impl Default for RouterConfigFactory where ::Err: std::fmt::Display, R: serde::Serialize + serde::de::DeserializeOwned, { fn default() -> Self { Self::from(RouterConfig::default) } } #[cfg(not(feature = "serde"))] impl Default for RouterConfigFactory where ::Err: std::fmt::Display, { fn default() -> Self { Self::from(RouterConfig::default) } } impl RouterConfig + 'static> From for RouterConfigFactory { fn from(value: F) -> Self { Self { config: RefCell::new(Some(Box::new(value))), } } } #[cfg(feature = "serde")] /// The props for [`Router`]. #[derive(Props)] pub struct RouterProps where ::Err: std::fmt::Display, R: serde::Serialize + serde::de::DeserializeOwned, { #[props(default, into)] config: RouterConfigFactory, } #[cfg(not(feature = "serde"))] /// The props for [`Router`]. #[derive(Props)] pub struct RouterProps where ::Err: std::fmt::Display, { #[props(default, into)] config: RouterConfigFactory, } impl Clone for RouterProps where ::Err: std::fmt::Display, { fn clone(&self) -> Self { todo!() } } #[cfg(not(feature = "serde"))] impl Default for RouterProps where ::Err: std::fmt::Display, { fn default() -> Self { Self { config: RouterConfigFactory::default(), } } } #[cfg(feature = "serde")] impl Default for RouterProps where ::Err: std::fmt::Display, R: serde::Serialize + serde::de::DeserializeOwned, { fn default() -> Self { Self { config: RouterConfigFactory::default(), } } } #[cfg(not(feature = "serde"))] impl PartialEq for RouterProps where ::Err: std::fmt::Display, { fn eq(&self, _: &Self) -> bool { // prevent the router from re-rendering when the initial url or config changes true } } #[cfg(feature = "serde")] impl PartialEq for RouterProps where ::Err: std::fmt::Display, R: serde::Serialize + serde::de::DeserializeOwned, { fn eq(&self, _: &Self) -> bool { // prevent the router from re-rendering when the initial url or config changes true } } #[cfg(not(feature = "serde"))] /// A component that renders the current route. pub fn Router(props: RouterProps) -> Element where ::Err: std::fmt::Display, { use crate::prelude::{outlet::OutletContext, RouterContext}; todo!(); // use_context_provider(|| { // RouterContext::new( // (props // .config // .config // .take() // .expect("use_context_provider ran twice"))(), // schedule_update_any(), // ) // }); // use_context_provider(|| OutletContext:: { // current_level: 0, // _marker: std::marker::PhantomData, // }); render! { Outlet:: {} } } #[cfg(feature = "serde")] /// A component that renders the current route. pub fn Router(cx: Scope>) -> Element where ::Err: std::fmt::Display, R: serde::Serialize + serde::de::DeserializeOwned, { use_context_provider(|| { RouterContext::new( (cx.props .config .config .take() .expect("use_context_provider ran twice"))(), cx.schedule_update_any(), ) }); use_context_provider(|| OutletContext:: { current_level: 0, _marker: std::marker::PhantomData, }); render! { Outlet:: {} } }