Przeglądaj źródła

allow extra fields in the enum not from the route

Evan Almloff 2 lat temu
rodzic
commit
1f68399e7b

+ 2 - 1
packages/router-macro/src/lib.rs

@@ -161,6 +161,7 @@ impl RouteEnum {
         quote! {
             impl std::fmt::Display for #name {
                 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                    #[allow(unused)]
                     match self {
                         #(#display_match)*
                     }
@@ -177,7 +178,7 @@ impl RouteEnum {
         let error_name = format_ident!("{}MatchError", self.name);
         let tokens = tree.roots.iter().map(|&id| {
             let route = tree.get(id).unwrap();
-            route.to_tokens(&tree, self.name.clone(), error_name.clone())
+            route.to_tokens(&self.nests, &tree, self.name.clone(), error_name.clone())
         });
 
         quote! {

+ 5 - 4
packages/router-macro/src/nest.rs

@@ -51,10 +51,11 @@ impl Nest {
 
 impl Nest {
     pub fn dynamic_segments(&self) -> impl Iterator<Item = TokenStream> + '_ {
-        self.segments
-            .iter()
-            .filter_map(|seg| seg.name())
-            .map(|i| quote! {#i})
+        self.dynamic_segments_names().map(|i| quote! {#i})
+    }
+
+    pub fn dynamic_segments_names(&self) -> impl Iterator<Item = Ident> + '_ {
+        self.segments.iter().filter_map(|seg| seg.name())
     }
 
     pub fn write(&self) -> TokenStream {

+ 31 - 2
packages/router-macro/src/route.rs

@@ -173,8 +173,37 @@ impl Route {
         })
     }
 
-    pub fn construct(&self, enum_name: Ident) -> TokenStream2 {
-        let segments = self.dynamic_segments();
+    pub fn construct(&self, nests: &[Nest], enum_name: Ident) -> TokenStream2 {
+        let segments = self.fields.named.iter().map(|f| {
+            let mut from_route = false;
+            for id in &self.nests {
+                let nest = &nests[id.0];
+                if nest
+                    .dynamic_segments_names()
+                    .any(|i| &i == f.ident.as_ref().unwrap())
+                {
+                    from_route = true
+                }
+            }
+            for segment in &self.segments {
+                match segment {
+                    RouteSegment::Dynamic(name, _) => {
+                        if name == f.ident.as_ref().unwrap() {
+                            from_route = true
+                        }
+                    }
+                    _ => {}
+                }
+            }
+
+            let name = f.ident.as_ref().unwrap();
+
+            if from_route {
+                quote! {#name}
+            } else {
+                quote! {#name: Default::default()}
+            }
+        });
         let name = &self.route_name;
 
         quote! {

+ 4 - 3
packages/router-macro/src/route_tree.rs

@@ -263,6 +263,7 @@ pub enum RouteTreeSegmentData<'a> {
 impl<'a> RouteTreeSegmentData<'a> {
     pub fn to_tokens(
         &self,
+        nests: &[Nest],
         tree: &RouteTree,
         enum_name: syn::Ident,
         error_enum_name: syn::Ident,
@@ -282,7 +283,7 @@ impl<'a> RouteTreeSegmentData<'a> {
 
                 let children = children.iter().map(|child| {
                     let child = tree.get(*child).unwrap();
-                    child.to_tokens(tree, enum_name.clone(), error_enum_name.clone())
+                    child.to_tokens(nests, tree, enum_name.clone(), error_enum_name.clone())
                 });
 
                 quote! {
@@ -310,7 +311,7 @@ impl<'a> RouteTreeSegmentData<'a> {
                     .enumerate()
                     .skip_while(|(_, seg)| matches!(seg, RouteSegment::Static(_)));
 
-                let construct_variant = route.construct(enum_name);
+                let construct_variant = route.construct(nests, enum_name);
                 let parse_query = route.parse_query();
 
                 let insure_not_trailing = route
@@ -349,7 +350,7 @@ impl<'a> RouteTreeSegmentData<'a> {
                     .iter()
                     .map(|child| {
                         let child = tree.get(*child).unwrap();
-                        child.to_tokens(tree, enum_name.clone(), error_enum_name.clone())
+                        child.to_tokens(nests, tree, enum_name.clone(), error_enum_name.clone())
                     })
                     .collect();
 

+ 1 - 4
packages/router/src/history/web_hash.rs

@@ -8,10 +8,7 @@ use web_sys::{History, ScrollRestoration, Window};
 
 use crate::routable::Routable;
 
-use super::{
-    web_scroll::{top_left, update_history, update_scroll},
-    HistoryProvider,
-};
+use super::HistoryProvider;
 
 const INITIAL_URL: &str = "dioxus-router-core://initial_url.invalid/";