Fix url encoding query and implement FromQueryArgument for Option<T> (#4213)

* Fix url encoding queries

* handle percent encoding hash fragments

* implement fromqueryargument for Option<T>

* fix tests

* fix typo
This commit is contained in:
Evan Almloff authored and GitHub committed 2025-06-02 13:14:53 -05:00
1 parent 662cf0d902
commit 9b16cbf254
13 files changed
+294 -30

No files matched your search

+88 -1
View File
@@ -1,5 +1,8 @@
use dioxus::prelude::*;
use std::str::FromStr;
use std::{
fmt::{self, Display},
str::FromStr,
};
#[component]
fn Root() -> Element {
@@ -75,3 +78,87 @@ fn without_trailing_slashes_parse() {
RouteWithoutTrailingSlash::Dynamic { id: 123 }
);
}
// Regression test for https://github.com/DioxusLabs/dioxus/issues/2984
#[test]
fn query_segments_parse() {
#[derive(Debug, Clone, PartialEq)]
enum Query {
Id(u64),
}
impl From<&str> for Query {
fn from(_: &str) -> Self {
// e.g. split query on `&` and split pairs on `=`
Query::Id(10)
}
}
impl Display for Query {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "id=10")
}
}
#[component]
fn Index(query: Query) -> Element {
rsx! {
h1 { "Index" }
}
}
#[derive(Debug, Clone, PartialEq, Routable)]
enum Route {
#[route("/?:..query")]
Index { query: Query },
}
let route = Route::Index {
query: Query::Id(10),
};
assert_eq!(route.to_string(), "/?id=10");
let parsed_route = "/?id=10".parse::<Route>().unwrap();
assert_eq!(parsed_route, route);
}
#[test]
fn optional_query_segments_parse() {
#[derive(Debug, Clone, PartialEq, Routable)]
enum Route {
#[route("/?:query&:other")]
Index { query: Option<u64>, other: u64 },
}
#[component]
fn Index(query: Option<u64>, other: u64) -> Element {
rsx! {
h1 { "Index" }
}
}
let route = Route::Index {
query: Some(10),
other: 20,
};
assert_eq!(route.to_string(), "/?query=10&other=20");
let parsed_route = "/?query=10&other=20".parse::<Route>().unwrap();
assert_eq!(parsed_route, route);
let route_without_query = Route::Index {
query: None,
other: 20,
};
assert_eq!(route_without_query.to_string(), "/?other=20");
let parsed_route_without_query = "/?other=20".parse::<Route>().unwrap();
assert_eq!(parsed_route_without_query, route_without_query);
let route_without_query_and_other = Route::Index {
query: None,
other: 0,
};
assert_eq!(route_without_query_and_other.to_string(), "/?other=0");
let parsed_route_without_query_and_other = "/".parse::<Route>().unwrap();
assert_eq!(
parsed_route_without_query_and_other,
route_without_query_and_other
);
}