Forráskód Böngészése

More WIP router implementation

Dave Rolsky 3 éve
szülő
commit
e06eac1
2 módosított fájl, 40 hozzáadás és 18 törlés
  1. 9 3
      examples/router.rs
  2. 31 15
      packages/router/src/hooks/use_route.rs

+ 9 - 3
examples/router.rs

@@ -2,6 +2,7 @@
 
 use dioxus::prelude::*;
 use dioxus::router::{Link, Route, Router};
+use serde::Deserialize;
 
 fn main() {
     dioxus::desktop::launch(app);
@@ -30,7 +31,7 @@ fn app(cx: Scope) -> Element {
 }
 
 fn BlogPost(cx: Scope) -> Element {
-    let post = dioxus::router::use_route(&cx).last_segment()?;
+    let post = dioxus::router::use_route(&cx).last_segment();
 
     cx.render(rsx! {
         div {
@@ -40,9 +41,14 @@ fn BlogPost(cx: Scope) -> Element {
     })
 }
 
+#[derive(Deserialize)]
+struct Query {
+    bold: bool,
+}
+
 fn User(cx: Scope) -> Element {
-    let post = dioxus::router::use_route(&cx).last_segment()?;
-    let bold = dioxus::router::use_route(&cx).param::<bool>("bold");
+    let post = dioxus::router::use_route(&cx).last_segment();
+    let query = dioxus::router::use_route(&cx).query::<Query>();
 
     cx.render(rsx! {
         div {

+ 31 - 15
packages/router/src/hooks/use_route.rs

@@ -1,20 +1,29 @@
 use dioxus_core::ScopeState;
-use gloo::history::Location;
+use gloo::history::{HistoryResult, Location};
+use serde::de::DeserializeOwned;
 use std::{rc::Rc, str::FromStr};
 
 use crate::RouterService;
 
-pub struct UseRoute<'a> {
+/// This struct provides is a wrapper around the internal router
+/// implementation, with methods for getting information about the current
+/// route.
+pub struct UseRoute {
     router: Rc<RouterService>,
-    cx: &'a ScopeState,
 }
 
-impl<'a> UseRoute<'a> {
-    /// Parse the query part of the URL
-    pub fn param<T>(&self, param: &str) -> Option<&T> {
-        todo!()
+impl UseRoute {
+    /// This method simply calls the [`Location::query`] method.
+    pub fn query<T>(&self) -> HistoryResult<T>
+    where
+        T: DeserializeOwned,
+    {
+        self.current_location().query::<T>()
     }
 
+    /// Returns the nth segment in the path. Paths that end with a slash have
+    /// the slash removed before determining the segments. If the path has
+    /// fewer segments than `n` then this method returns `None`.
     pub fn nth_segment(&self, n: usize) -> Option<String> {
         let mut segments = self.path_segments();
         let len = segments.len();
@@ -24,13 +33,12 @@ impl<'a> UseRoute<'a> {
         Some(segments.remove(n))
     }
 
-    pub fn last_segment(&self) -> Option<String> {
+    /// Returns the last segment in the path. Paths that end with a slash have
+    /// the slash removed before determining the segments. The root path, `/`,
+    /// will return an empty string.
+    pub fn last_segment(&self) -> String {
         let mut segments = self.path_segments();
-        let len = segments.len();
-        if len == 0 {
-            return None;
-        }
-        Some(segments.remove(len - 1))
+        segments.remove(segments.len() - 1)
     }
 
     /// Get the named parameter from the path, as defined in your router. The
@@ -47,21 +55,29 @@ impl<'a> UseRoute<'a> {
             .and_then(|v| Some(v.parse::<T>()))
     }
 
+    /// Returns the [Location] for the current route.
     pub fn current_location(&self) -> Location {
         self.router.current_location()
     }
 
     fn path_segments(&self) -> Vec<String> {
         let location = self.router.current_location();
+        let path = location.path();
+        if path == "/" {
+            return vec![String::new()];
+        }
         let stripped = &location.path()[1..];
         stripped.split('/').map(str::to_string).collect::<Vec<_>>()
     }
 }
 
-pub fn use_route<'a>(cx: &'a ScopeState) -> UseRoute<'a> {
+/// This hook provides access to information about the current location in the
+/// context of a [`Router`]. If this function is called outside of a `Router`
+/// component it will panic.
+pub fn use_route(cx: &ScopeState) -> UseRoute {
     let router = cx
         .consume_context::<RouterService>()
         .expect("Cannot call use_route outside the scope of a Router component")
         .clone();
-    UseRoute { router, cx }
+    UseRoute { router }
 }