123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- 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<R: Routable> {
- #[allow(clippy::type_complexity)]
- config: RefCell<Option<Box<dyn FnOnce() -> RouterConfig<R>>>>,
- }
- #[cfg(feature = "serde")]
- impl<R: Routable> Default for RouterConfigFactory<R>
- where
- <R as FromStr>::Err: std::fmt::Display,
- R: serde::Serialize + serde::de::DeserializeOwned,
- {
- fn default() -> Self {
- Self::from(RouterConfig::default)
- }
- }
- #[cfg(not(feature = "serde"))]
- impl<R: Routable> Default for RouterConfigFactory<R>
- where
- <R as FromStr>::Err: std::fmt::Display,
- {
- fn default() -> Self {
- Self::from(RouterConfig::default)
- }
- }
- impl<R: Routable, F: FnOnce() -> RouterConfig<R> + 'static> From<F> for RouterConfigFactory<R> {
- 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<R: Routable>
- where
- <R as FromStr>::Err: std::fmt::Display,
- R: serde::Serialize + serde::de::DeserializeOwned,
- {
- #[props(default, into)]
- config: RouterConfigFactory<R>,
- }
- #[cfg(not(feature = "serde"))]
- /// The props for [`Router`].
- #[derive(Props)]
- pub struct RouterProps<R: Routable>
- where
- <R as FromStr>::Err: std::fmt::Display,
- {
- #[props(default, into)]
- config: RouterConfigFactory<R>,
- }
- impl<T: Routable> Clone for RouterProps<T>
- where
- <T as FromStr>::Err: std::fmt::Display,
- {
- fn clone(&self) -> Self {
- todo!()
- }
- }
- #[cfg(not(feature = "serde"))]
- impl<R: Routable> Default for RouterProps<R>
- where
- <R as FromStr>::Err: std::fmt::Display,
- {
- fn default() -> Self {
- Self {
- config: RouterConfigFactory::default(),
- }
- }
- }
- #[cfg(feature = "serde")]
- impl<R: Routable> Default for RouterProps<R>
- where
- <R as FromStr>::Err: std::fmt::Display,
- R: serde::Serialize + serde::de::DeserializeOwned,
- {
- fn default() -> Self {
- Self {
- config: RouterConfigFactory::default(),
- }
- }
- }
- #[cfg(not(feature = "serde"))]
- impl<R: Routable> PartialEq for RouterProps<R>
- where
- <R as FromStr>::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<R: Routable> PartialEq for RouterProps<R>
- where
- <R as FromStr>::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<R: Routable + Clone>(props: RouterProps<R>) -> Element
- where
- <R as FromStr>::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::<R> {
- // current_level: 0,
- // _marker: std::marker::PhantomData,
- // });
- render! { Outlet::<R> {} }
- }
- #[cfg(feature = "serde")]
- /// A component that renders the current route.
- pub fn Router<R: Routable + Clone>(cx: Scope<RouterProps<R>>) -> Element
- where
- <R as FromStr>::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::<R> {
- current_level: 0,
- _marker: std::marker::PhantomData,
- });
- render! { Outlet::<R> {} }
- }
|