feat: add OptionalParamSegment (closes #2896) (#3140)

This commit is contained in:
Greg Johnston
2024-10-21 21:15:14 -04:00
committed by GitHub
parent 7904e0c395
commit d0ef7b904d
20 changed files with 537 additions and 272 deletions

View File

@@ -18,4 +18,4 @@ proc-macro2 = "1.0"
quote = "1.0"
[dev-dependencies]
leptos_router = { version = "0.7.0-beta" }
leptos_router = { path = "../router" }

View File

@@ -14,12 +14,16 @@ const RFC3986_PCHAR_OTHER: [char; 1] = ['@'];
/// # Examples
///
/// ```rust
/// use leptos_router::{path, ParamSegment, StaticSegment, WildcardSegment};
/// use leptos_router::{
/// path, OptionalParamSegment, ParamSegment, StaticSegment,
/// WildcardSegment,
/// };
///
/// let path = path!("/foo/:bar/*any");
/// let path = path!("/foo/:bar/:baz?/*any");
/// let output = (
/// StaticSegment("foo"),
/// ParamSegment("bar"),
/// OptionalParamSegment("baz"),
/// WildcardSegment("any"),
/// );
///
@@ -41,6 +45,7 @@ struct Segments(pub Vec<Segment>);
enum Segment {
Static(String),
Param(String),
OptionalParam(String),
Wildcard(String),
}
@@ -93,7 +98,11 @@ impl SegmentParser {
for segment in current_str.split('/') {
if let Some(segment) = segment.strip_prefix(':') {
segments.push(Segment::Param(segment.to_string()));
if let Some(segment) = segment.strip_suffix('?') {
segments.push(Segment::OptionalParam(segment.to_string()));
} else {
segments.push(Segment::Param(segment.to_string()));
}
} else if let Some(segment) = segment.strip_prefix('*') {
segments.push(Segment::Wildcard(segment.to_string()));
} else {
@@ -156,6 +165,10 @@ impl ToTokens for Segment {
Segment::Param(p) => {
tokens.extend(quote! { leptos_router::ParamSegment(#p) });
}
Segment::OptionalParam(p) => {
tokens
.extend(quote! { leptos_router::OptionalParamSegment(#p) });
}
}
}
}

View File

@@ -1,4 +1,6 @@
use leptos_router::{ParamSegment, StaticSegment, WildcardSegment};
use leptos_router::{
OptionalParamSegment, ParamSegment, StaticSegment, WildcardSegment,
};
use leptos_router_macro::path;
#[test]
@@ -86,6 +88,12 @@ fn parses_single_param() {
assert_eq!(output, (ParamSegment("id"),));
}
#[test]
fn parses_optional_param() {
let output = path!("/:id?");
assert_eq!(output, (OptionalParamSegment("id"),));
}
#[test]
fn parses_static_and_param() {
let output = path!("/home/:id");
@@ -144,9 +152,22 @@ fn parses_consecutive_param() {
);
}
#[test]
fn parses_consecutive_optional_param() {
let output = path!("/:foo?/:bar?/:baz?");
assert_eq!(
output,
(
OptionalParamSegment("foo"),
OptionalParamSegment("bar"),
OptionalParamSegment("baz")
)
);
}
#[test]
fn parses_complex() {
let output = path!("/home/:id/foo/:bar/*any");
let output = path!("/home/:id/foo/:bar/:baz?/*any");
assert_eq!(
output,
(
@@ -154,6 +175,7 @@ fn parses_complex() {
ParamSegment("id"),
StaticSegment("foo"),
ParamSegment("bar"),
OptionalParamSegment("baz"),
WildcardSegment("any"),
)
);