fix reversed nests
This commit is contained in:
1 parent
35a3880b88
commit
d19a33d59c
5 files changed
+64
-51
No files matched your search
@@ -364,10 +364,7 @@ impl RouteEnum {
|
|||||||
let parser = |input: ParseStream| {
|
let parser = |input: ParseStream| {
|
||||||
let bang: Option<Token![!]> = input.parse().ok();
|
let bang: Option<Token![!]> = input.parse().ok();
|
||||||
let exclude = bang.is_some();
|
let exclude = bang.is_some();
|
||||||
Ok((
|
Ok((exclude, Layout::parse(input, nest_stack.clone())?))
|
||||||
exclude,
|
|
||||||
Layout::parse(input, nest_stack.iter().rev().cloned().collect())?,
|
|
||||||
))
|
|
||||||
};
|
};
|
||||||
let (exclude, layout): (bool, Layout) = attr.parse_args_with(parser)?;
|
let (exclude, layout): (bool, Layout) = attr.parse_args_with(parser)?;
|
||||||
|
|
||||||
@@ -389,19 +386,14 @@ impl RouteEnum {
|
|||||||
layout_stack.pop();
|
layout_stack.pop();
|
||||||
} else if attr.path.is_ident("redirect") {
|
} else if attr.path.is_ident("redirect") {
|
||||||
let parser = |input: ParseStream| {
|
let parser = |input: ParseStream| {
|
||||||
Redirect::parse(
|
Redirect::parse(input, nest_stack.clone(), redirects.len())
|
||||||
input,
|
|
||||||
nest_stack.iter().rev().cloned().collect(),
|
|
||||||
redirects.len(),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
let redirect = attr.parse_args_with(parser)?;
|
let redirect = attr.parse_args_with(parser)?;
|
||||||
redirects.push(redirect);
|
redirects.push(redirect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut active_nests = nest_stack.clone();
|
let active_nests = nest_stack.clone();
|
||||||
active_nests.reverse();
|
|
||||||
let mut active_layouts = layout_stack.clone();
|
let mut active_layouts = layout_stack.clone();
|
||||||
active_layouts.retain(|&id| !excluded.contains(&id));
|
active_layouts.retain(|&id| !excluded.contains(&id));
|
||||||
|
|
||||||
|
|||||||
@@ -186,26 +186,37 @@ impl Route {
|
|||||||
pub fn display_match(&self, nests: &[Nest]) -> TokenStream2 {
|
pub fn display_match(&self, nests: &[Nest]) -> TokenStream2 {
|
||||||
let name = &self.route_name;
|
let name = &self.route_name;
|
||||||
let dynamic_segments = self.dynamic_segments();
|
let dynamic_segments = self.dynamic_segments();
|
||||||
let write_layouts = self.nests.iter().map(|id| nests[id.0].write());
|
|
||||||
let write_segments = self.segments.iter().map(|s| s.write_segment());
|
|
||||||
let write_query = self.query.as_ref().map(|q| q.write());
|
let write_query = self.query.as_ref().map(|q| q.write());
|
||||||
|
|
||||||
match &self.ty {
|
match &self.ty {
|
||||||
RouteType::Child(field) => {
|
RouteType::Child(field) => {
|
||||||
|
let write_nests = self.nests.iter().map(|id| nests[id.0].write());
|
||||||
|
let write_segments = self.segments.iter().map(|s| s.write_segment());
|
||||||
let child = field.ident.as_ref().unwrap();
|
let child = field.ident.as_ref().unwrap();
|
||||||
quote! {
|
quote! {
|
||||||
Self::#name { #(#dynamic_segments,)* #child } => {
|
Self::#name { #(#dynamic_segments,)* #child } => {
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
#(#write_layouts)*
|
use std::fmt::Write;
|
||||||
#(#write_segments)*
|
let mut route = String::new();
|
||||||
#child.fmt(f);
|
{
|
||||||
|
let f = &mut route;
|
||||||
|
#(#write_nests)*
|
||||||
|
#(#write_segments)*
|
||||||
|
}
|
||||||
|
if route.ends_with('/') {
|
||||||
|
route.pop();
|
||||||
|
}
|
||||||
|
f.write_str(&route)?;
|
||||||
|
#child.fmt(f)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RouteType::Leaf { .. } => {
|
RouteType::Leaf { .. } => {
|
||||||
|
let write_nests = self.nests.iter().map(|id| nests[id.0].write());
|
||||||
|
let write_segments = self.segments.iter().map(|s| s.write_segment());
|
||||||
quote! {
|
quote! {
|
||||||
Self::#name { #(#dynamic_segments,)* } => {
|
Self::#name { #(#dynamic_segments,)* } => {
|
||||||
#(#write_layouts)*
|
#(#write_nests)*
|
||||||
#(#write_segments)*
|
#(#write_segments)*
|
||||||
#write_query
|
#write_query
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ impl<'a> RouteTreeSegmentData<'a> {
|
|||||||
#(#children)*
|
#(#children)*
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errors.push(#error_enum_name::#enum_varient(#varient_parse_error::#error_ident))
|
errors.push(#error_enum_name::#enum_varient(#varient_parse_error::#error_ident(segment.to_string())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,10 +58,11 @@ impl RouteSegment {
|
|||||||
quote! {
|
quote! {
|
||||||
{
|
{
|
||||||
let mut segments = segments.clone();
|
let mut segments = segments.clone();
|
||||||
let parsed = if let Some(#segment) = segments.next() {
|
let segment = segments.next();
|
||||||
|
let parsed = if let Some(#segment) = segment {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(#error_enum_name::#error_enum_varient(#inner_parse_enum::#error_name))
|
Err(#error_enum_name::#error_enum_varient(#inner_parse_enum::#error_name(segment.map(|s|s.to_string()).unwrap_or_default())))
|
||||||
};
|
};
|
||||||
match parsed {
|
match parsed {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
@@ -234,8 +235,8 @@ pub(crate) fn create_error_type(
|
|||||||
let error_name = segment.error_name(i);
|
let error_name = segment.error_name(i);
|
||||||
match segment {
|
match segment {
|
||||||
RouteSegment::Static(index) => {
|
RouteSegment::Static(index) => {
|
||||||
error_variants.push(quote! { #error_name });
|
error_variants.push(quote! { #error_name(String) });
|
||||||
display_match.push(quote! { Self::#error_name => write!(f, "Static segment '{}' did not match", #index)? });
|
display_match.push(quote! { Self::#error_name(found) => write!(f, "Static segment '{}' did not match instead found '{found}'", #index)? });
|
||||||
}
|
}
|
||||||
RouteSegment::Dynamic(ident, ty) => {
|
RouteSegment::Dynamic(ident, ty) => {
|
||||||
let missing_error = segment.missing_error_name().unwrap();
|
let missing_error = segment.missing_error_name().unwrap();
|
||||||
|
|||||||
@@ -96,21 +96,28 @@ fn Route3(cx: Scope, dynamic: String) -> Element {
|
|||||||
p { "Site Map" }
|
p { "Site Map" }
|
||||||
pre { "{site_map:#?}" }
|
pre { "{site_map:#?}" }
|
||||||
p { "Dynamic link" }
|
p { "Dynamic link" }
|
||||||
if let Ok(route) = parsed {
|
match parsed {
|
||||||
if route != current_route {
|
Ok(route) => {
|
||||||
|
if route != current_route {
|
||||||
|
render! {
|
||||||
|
Link {
|
||||||
|
target: route.clone(),
|
||||||
|
"{route}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
render! {
|
render! {
|
||||||
Link {
|
pre {
|
||||||
target: route.clone(),
|
color: "red",
|
||||||
"{route}"
|
"Invalid route:\n{err}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,24 +125,26 @@ fn Route3(cx: Scope, dynamic: String) -> Element {
|
|||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[derive(Clone, Debug, PartialEq, Routable)]
|
#[derive(Clone, Debug, PartialEq, Routable)]
|
||||||
enum Route {
|
enum Route {
|
||||||
// Nests with parameters have types taken from child routes
|
#[nest("/test")]
|
||||||
#[nest("/user/:user_id")]
|
// Nests with parameters have types taken from child routes
|
||||||
// Everything inside the nest has the added parameter `user_id: usize`
|
#[nest("/user/:user_id")]
|
||||||
// UserFrame is a layout component that will receive the `user_id: usize` parameter
|
// Everything inside the nest has the added parameter `user_id: usize`
|
||||||
#[layout(UserFrame)]
|
// UserFrame is a layout component that will receive the `user_id: usize` parameter
|
||||||
#[route("/:dynamic?:query")]
|
#[layout(UserFrame)]
|
||||||
Route1 {
|
#[route("/:dynamic?:query")]
|
||||||
// The type is taken from the first instance of the dynamic parameter
|
Route1 {
|
||||||
user_id: usize,
|
// The type is taken from the first instance of the dynamic parameter
|
||||||
dynamic: usize,
|
user_id: usize,
|
||||||
query: String,
|
dynamic: usize,
|
||||||
extra: String,
|
query: String,
|
||||||
},
|
extra: String,
|
||||||
#[route("/hello_world")]
|
},
|
||||||
// You can opt out of the layout by using the `!` prefix
|
#[route("/hello_world")]
|
||||||
#[layout(!UserFrame)]
|
// You can opt out of the layout by using the `!` prefix
|
||||||
Route2 { user_id: usize },
|
#[layout(!UserFrame)]
|
||||||
#[end_layout]
|
Route2 { user_id: usize },
|
||||||
|
#[end_layout]
|
||||||
|
#[end_nest]
|
||||||
#[end_nest]
|
#[end_nest]
|
||||||
#[redirect("/:id/user", |id: usize| Route::Route3 { dynamic: id.to_string()})]
|
#[redirect("/:id/user", |id: usize| Route::Route3 { dynamic: id.to_string()})]
|
||||||
#[route("/:dynamic")]
|
#[route("/:dynamic")]
|
||||||
|
|||||||
Reference in new issue
Block a user