allow extra fields in the enum not from the route

This commit is contained in:
Evan Almloff 2023-05-23 13:57:50 -05:00
parent 46017d5b7e
commit 1f68399e7b
5 changed files with 43 additions and 14 deletions

View file

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

View file

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

View file

@ -173,8 +173,37 @@ impl Route {
}) })
} }
pub fn construct(&self, enum_name: Ident) -> TokenStream2 { pub fn construct(&self, nests: &[Nest], enum_name: Ident) -> TokenStream2 {
let segments = self.dynamic_segments(); 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; let name = &self.route_name;
quote! { quote! {

View file

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

View file

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