Implement hash fragments in the router (#2320)

* implement hash fragments in the router

* clean up query and search example

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2024-04-25 14:30:25 -04:00
1 parent dd8e69635b
commit 08da9a1253
17 files changed
+550 -190

No files matched your search

+68 -2
View File
@@ -51,6 +51,66 @@ impl QuerySegment {
}
}
}
pub fn parse_from_str<'a>(
route_span: proc_macro2::Span,
mut fields: impl Iterator<Item = (&'a Ident, &'a Type)>,
query: &str,
) -> syn::Result<Self> {
// check if the route has a query string
if let Some(query) = query.strip_prefix(":..") {
let query_ident = Ident::new(query, proc_macro2::Span::call_site());
let field = fields.find(|(name, _)| *name == &query_ident);
let ty = if let Some((_, ty)) = field {
ty.clone()
} else {
return Err(syn::Error::new(
route_span,
format!("Could not find a field with the name '{}'", query_ident),
));
};
Ok(QuerySegment::Single(FullQuerySegment {
ident: query_ident,
ty,
}))
} else {
let mut query_arguments = Vec::new();
for segment in query.split('&') {
if segment.is_empty() {
return Err(syn::Error::new(
route_span,
"Query segments should be non-empty",
));
}
if let Some(query_argument) = segment.strip_prefix(':') {
let query_ident = Ident::new(query_argument, proc_macro2::Span::call_site());
let field = fields.find(|(name, _)| *name == &query_ident);
let ty = if let Some((_, ty)) = field {
ty.clone()
} else {
return Err(syn::Error::new(
route_span,
format!("Could not find a field with the name '{}'", query_ident),
));
};
query_arguments.push(QueryArgument {
ident: query_ident,
ty,
});
} else {
return Err(syn::Error::new(
route_span,
"Query segments should be a : followed by the name of the query argument",
));
}
}
Ok(QuerySegment::Segments(query_arguments))
}
}
}
#[derive(Debug)]
@@ -71,7 +131,10 @@ impl FullQuerySegment {
pub fn write(&self) -> TokenStream2 {
let ident = &self.ident;
quote! {
write!(f, "?{}", #ident)?;
{
let as_string = #ident.to_string();
write!(f, "?{}", dioxus_router::exports::urlencoding::encode(&as_string))?;
}
}
}
}
@@ -97,7 +160,10 @@ impl QueryArgument {
pub fn write(&self) -> TokenStream2 {
let ident = &self.ident;
quote! {
write!(f, "{}={}", stringify!(#ident), #ident)?;
{
let as_string = #ident.to_string();
write!(f, "{}={}", stringify!(#ident), dioxus_router::exports::urlencoding::encode(&as_string))?;
}
}
}
}