fix errors for nested routes

This commit is contained in:
Evan Almloff committed 2023-06-28 11:27:11 -07:00
1 parent 7b1f0c9412
commit a7f7aad947
7 files changed
+64 -22

No files matched your search

+2 -2
View File
@@ -61,11 +61,11 @@ web-sys = { version = "0.3.61", features = ["Window", "Document", "Element", "Ht
[features] [features]
default = ["hot-reload", "default-tls"] default = ["hot-reload", "default-tls"]
router = ["dioxus-router"] router = ["dioxus-router"]
hot-reload = ["serde_json", "tokio-stream", "futures-util"] hot-reload = ["serde_json", "futures-util"]
warp = ["dep:warp", "http-body", "ssr"] warp = ["dep:warp", "http-body", "ssr"]
axum = ["dep:axum", "tower-http", "ssr"] axum = ["dep:axum", "tower-http", "ssr"]
salvo = ["dep:salvo", "ssr"] salvo = ["dep:salvo", "ssr"]
ssr = ["server_fn/ssr", "tokio", "dioxus-ssr", "hyper", "http", "dioxus-router/ssr"] ssr = ["server_fn/ssr", "tokio", "dioxus-ssr", "hyper", "http", "dioxus-router/ssr", "tokio-stream"]
default-tls = ["server_fn/default-tls"] default-tls = ["server_fn/default-tls"]
rustls = ["server_fn/rustls"] rustls = ["server_fn/rustls"]
@@ -7,7 +7,7 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
dioxus-web = { workspace = true, features=["hydrate"], optional = true } dioxus-web = { workspace = true, features = ["hydrate"], optional = true }
dioxus = { workspace = true } dioxus = { workspace = true }
dioxus-fullstack = { workspace = true } dioxus-fullstack = { workspace = true }
axum = { version = "0.6.12", optional = true } axum = { version = "0.6.12", optional = true }
+1 -1
View File
@@ -82,6 +82,6 @@ impl Nest {
pub fn error_type(&self) -> TokenStream { pub fn error_type(&self) -> TokenStream {
let error_name = self.error_ident(); let error_name = self.error_ident();
create_error_type(error_name, &self.segments) create_error_type(error_name, &self.segments, None)
} }
} }
+1 -1
View File
@@ -30,7 +30,7 @@ impl Redirect {
pub fn error_type(&self) -> TokenStream { pub fn error_type(&self) -> TokenStream {
let error_name = self.error_ident(); let error_name = self.error_ident();
create_error_type(error_name, &self.segments) create_error_type(error_name, &self.segments, None)
} }
pub fn parse_query(&self) -> TokenStream { pub fn parse_query(&self) -> TokenStream {
+8 -13
View File
@@ -308,20 +308,11 @@ impl Route {
RouteType::Child(field) => { RouteType::Child(field) => {
let name = &self.route_name; let name = &self.route_name;
let child_name = field.ident.as_ref().unwrap(); let child_name = field.ident.as_ref().unwrap();
let ty = &field.ty;
quote! { quote! {
{ #enum_name::#name {
let mut trailing = String::new(); #child_name,
for seg in segments { #(#segments,)*
trailing += seg;
trailing += "/";
}
trailing.pop();
#enum_name::#name {
#child_name: #ty::from_str(&trailing).unwrap(),
#(#segments,)*
}
} }
} }
} }
@@ -343,8 +334,12 @@ impl Route {
pub fn error_type(&self) -> TokenStream2 { pub fn error_type(&self) -> TokenStream2 {
let error_name = self.error_ident(); let error_name = self.error_ident();
let child_type = match &self.ty {
RouteType::Child(field) => Some(&field.ty),
RouteType::Leaf { .. } => None,
};
create_error_type(error_name, &self.segments) create_error_type(error_name, &self.segments, child_type)
} }
pub fn parse_query(&self) -> TokenStream2 { pub fn parse_query(&self) -> TokenStream2 {
+27 -2
View File
@@ -343,7 +343,7 @@ impl<'a> RouteTreeSegmentData<'a> {
RouteType::Child(_) => false, RouteType::Child(_) => false,
}; };
print_route_segment( let print_route_segment = print_route_segment(
route_segments.peekable(), route_segments.peekable(),
return_constructed( return_constructed(
insure_not_trailing, insure_not_trailing,
@@ -356,7 +356,32 @@ impl<'a> RouteTreeSegmentData<'a> {
&error_enum_name, &error_enum_name,
enum_varient, enum_varient,
&varient_parse_error, &varient_parse_error,
) );
match &route.ty {
RouteType::Child(child) => {
let ty = &child.ty;
let child_name = &child.ident;
quote! {
let mut trailing = String::new();
for seg in segments.clone() {
trailing += seg;
trailing += "/";
}
trailing.pop();
match #ty::from_str(&trailing).map_err(|err| #error_enum_name::#enum_varient(#varient_parse_error::ChildRoute(err))) {
Ok(#child_name) => {
#print_route_segment
}
Err(err) => {
errors.push(err);
}
}
}
}
RouteType::Leaf { .. } => print_route_segment,
}
} }
Self::Nest { nest, children } => { Self::Nest { nest, children } => {
// At this point, we have matched all static segments, so we can just check if the remaining segments match the route // At this point, we have matched all static segments, so we can just check if the remaining segments match the route
+24 -2
View File
@@ -222,7 +222,11 @@ pub fn parse_route_segments<'a>(
Ok((route_segments, parsed_query)) Ok((route_segments, parsed_query))
} }
pub(crate) fn create_error_type(error_name: Ident, segments: &[RouteSegment]) -> TokenStream2 { pub(crate) fn create_error_type(
error_name: Ident,
segments: &[RouteSegment],
child_type: Option<&Type>,
) -> TokenStream2 {
let mut error_variants = Vec::new(); let mut error_variants = Vec::new();
let mut display_match = Vec::new(); let mut display_match = Vec::new();
@@ -249,11 +253,28 @@ pub(crate) fn create_error_type(error_name: Ident, segments: &[RouteSegment]) ->
} }
} }
let child_type_variant = child_type
.map(|child_type| {
quote! { ChildRoute(<#child_type as std::str::FromStr>::Err) }
})
.into_iter();
let child_type_error = child_type
.map(|_| {
quote! {
Self::ChildRoute(error) => {
write!(f, "{}", error)?
}
}
})
.into_iter();
quote! { quote! {
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum #error_name { pub enum #error_name {
ExtraSegments(String), ExtraSegments(String),
#(#child_type_variant,)*
#(#error_variants,)* #(#error_variants,)*
} }
@@ -262,7 +283,8 @@ pub(crate) fn create_error_type(error_name: Ident, segments: &[RouteSegment]) ->
match self { match self {
Self::ExtraSegments(segments) => { Self::ExtraSegments(segments) => {
write!(f, "Found additional trailing segments: {}", segments)? write!(f, "Found additional trailing segments: {}", segments)?
} },
#(#child_type_error,)*
#(#display_match,)* #(#display_match,)*
} }
Ok(()) Ok(())