From 7d2466ff28775ee9276857f434f6f3e19dc4a637 Mon Sep 17 00:00:00 2001 From: Adrian Wannenmacher Date: Tue, 13 Dec 2022 11:09:24 +0100 Subject: [PATCH] make hooks return a result instead of an option --- packages/router/Cargo.toml | 1 + packages/router/src/error.rs | 8 ++++++++ packages/router/src/hooks/use_navigate.rs | 23 +++++++++------------ packages/router/src/hooks/use_route.rs | 25 +++++++++++------------ packages/router/src/lib.rs | 4 ++++ 5 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 packages/router/src/error.rs diff --git a/packages/router/Cargo.toml b/packages/router/Cargo.toml index 47295ace9..74f7cffeb 100644 --- a/packages/router/Cargo.toml +++ b/packages/router/Cargo.toml @@ -18,6 +18,7 @@ dioxus-router-core = { path = "../router-core"} futures-channel = "0.3.25" futures-util = "0.3.25" log = "0.4.17" +thiserror = "1.0.37" # for wasm diff --git a/packages/router/src/error.rs b/packages/router/src/error.rs new file mode 100644 index 000000000..294e68b99 --- /dev/null +++ b/packages/router/src/error.rs @@ -0,0 +1,8 @@ +/// Errors that may occur during routing. +#[derive(Debug, thiserror::Error)] +pub enum RouterError { + /// A hook that needs access to a router was called inside a component, that has no parent + /// calling the [`use_router`](crate::hooks::use_router) hook. + #[error("component needing access not inside router")] + NotInsideRouter, +} diff --git a/packages/router/src/hooks/use_navigate.rs b/packages/router/src/hooks/use_navigate.rs index 134c0aa83..c09b8af75 100644 --- a/packages/router/src/hooks/use_navigate.rs +++ b/packages/router/src/hooks/use_navigate.rs @@ -1,15 +1,14 @@ use dioxus::prelude::{ScopeId, ScopeState}; use dioxus_router_core::Navigator; -use log::error; -use crate::utils::use_router_internal::use_router_internal; +use crate::{RouterError, utils::use_router_internal::use_router_internal}; /// A hook that allows for programmatic navigation. /// /// # Return values -/// - [`None`], when the calling component is not nested within another component calling the -/// [`use_router`] hook. -/// - Otherwise [`Some`]. +/// - [`RouterError::NotInsideRouter`], when the calling component is not nested within another +/// component calling the [`use_router`] hook. +/// - Otherwise [`Ok`]. /// /// # Panic /// - When the calling component is not nested within another component calling the [`use_router`] @@ -36,7 +35,7 @@ use crate::utils::use_router_internal::use_router_internal; /// } /// /// fn Redirect(cx: Scope) -> Element { -/// let nav = use_navigate(&cx).unwrap(); +/// let nav = use_navigate(&cx)?; /// nav.push("/content"); /// render! { () } /// } @@ -58,16 +57,14 @@ use crate::utils::use_router_internal::use_router_internal; /// # assert_eq!(dioxus_ssr::render(&vdom), "

App

Content

"); /// ``` #[must_use] -pub fn use_navigate(cx: &ScopeState) -> Option> { +pub fn use_navigate(cx: &ScopeState) -> Result, RouterError> { match use_router_internal(cx) { - Some(r) => Some(r.sender.clone().into()), + Some(r) => Ok(r.sender.clone().into()), + #[allow(unreachable_code)] None => { - let msg = "`use_navigate` must have access to a parent router"; - error!("{msg}, will be inactive"); #[cfg(debug_assertions)] - panic!("{}", msg); - #[cfg(not(debug_assertions))] - None + panic!("`use_navigate` must have access to a parent router"); + Err(RouterError::NotInsideRouter) } } } diff --git a/packages/router/src/hooks/use_route.rs b/packages/router/src/hooks/use_route.rs index 9f1a2c5b3..5b8b83e06 100644 --- a/packages/router/src/hooks/use_route.rs +++ b/packages/router/src/hooks/use_route.rs @@ -1,16 +1,15 @@ use async_rwlock::RwLockReadGuard; use dioxus::{core::Component, prelude::ScopeState}; use dioxus_router_core::RouterState; -use log::error; -use crate::utils::use_router_internal::use_router_internal; +use crate::{RouterError, utils::use_router_internal::use_router_internal}; /// A hook that provides access to information about the current routing location. /// /// # Return values -/// - [`None`], when the calling component is not nested within another component calling the -/// [`use_router`] hook. -/// - Otherwise [`Some`]. +/// - [`RouterError::NotInsideRouter`], when the calling component is not nested within another +/// component calling the [`use_router`] hook. +/// - Otherwise [`Ok`]. /// /// # Important usage information /// Make sure to [`drop`] the returned [`RwLockReadGuard`] when done rendering. Otherwise the router @@ -42,7 +41,7 @@ use crate::utils::use_router_internal::use_router_internal; /// } /// /// fn Content(cx: Scope) -> Element { -/// let state = use_route(&cx).unwrap(); +/// let state = use_route(&cx)?; /// let path = state.path.clone(); /// /// render! { @@ -58,20 +57,20 @@ use crate::utils::use_router_internal::use_router_internal; /// /// [`use_router`]: super::use_router #[must_use] -pub fn use_route<'a>(cx: &'a ScopeState) -> Option>> { +pub fn use_route<'a>( + cx: &'a ScopeState, +) -> Result>, RouterError> { match use_router_internal(cx) { Some(r) => loop { if let Some(s) = r.state.try_read() { - break Some(s); + break Ok(s); } }, + #[allow(unreachable_code)] None => { - let msg = "`use_route` must have access to a parent router"; - error!("{msg}, will be inactive"); #[cfg(debug_assertions)] - panic!("{}", msg); - #[cfg(not(debug_assertions))] - None + panic!("`use_route` must have access to a parent router"); + Err(RouterError::NotInsideRouter) } } } diff --git a/packages/router/src/lib.rs b/packages/router/src/lib.rs index 30f3a610f..b69fb77c0 100644 --- a/packages/router/src/lib.rs +++ b/packages/router/src/lib.rs @@ -15,6 +15,10 @@ mod contexts { pub(crate) mod router; } +#[forbid(missing_docs)] +mod error; +pub use error::RouterError; + pub mod history { pub use dioxus_router_core::history::*; }