Skip to content

Commit

Permalink
stash
Browse files Browse the repository at this point in the history
  • Loading branch information
gbj committed Oct 12, 2023
1 parent f3508ce commit 468e167
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 18 deletions.
4 changes: 2 additions & 2 deletions router/src/history/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ impl TryFrom<&str> for Url {
type Error = String;

fn try_from(url: &str) -> Result<Self, Self::Error> {
let fake_host = "http://leptos";
let url = web_sys::Url::new_with_base(url, fake_host).map_js_error()?;
let url =
web_sys::Url::new(&format!("http://leptos{url}")).map_js_error()?;
Ok(Self {
origin: url.origin(),
pathname: url.pathname(),
Expand Down
44 changes: 28 additions & 16 deletions router/src/matching/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ impl Matcher {
};
let segments = pattern
.split('/')
.filter(|n| !n.is_empty())
.map(|n| n.to_string())
.collect::<Vec<_>>();

Expand All @@ -57,6 +56,8 @@ impl Matcher {
let loc_len = loc_segments.len();
let len_diff: i32 = loc_len as i32 - self.len as i32;

leptos::logging::log!("{:?}\n{loc_segments:?}", self.segments);

// quick path: not a match if
// 1) matcher has add'l segments not found in location
// 2) location has add'l segments, there's no splat, and partial matches not allowed
Expand All @@ -70,27 +71,38 @@ impl Matcher {
let mut path = String::new();
let mut params = ParamsMap::new();

for (segment, loc_segment) in
self.segments.iter().zip(loc_segments.iter())
{
if let Some(param_name) = segment.strip_prefix(':') {
params.insert(param_name.into(), (*loc_segment).into());
} else if segment != loc_segment {
// if any segment doesn't match and isn't a param, there's no path match
return None;
let segments = self.segments.iter();
let mut loc_segments_iter = loc_segments.iter();
for segment in segments {
// if it's a splat, move on
if segment.starts_with('*') {
_ = loc_segments_iter.next();
break;
}

path.push('/');
path.push_str(loc_segment);
if let Some(loc_segment) = loc_segments_iter.next() {
if let Some(param_name) = segment.strip_prefix(':') {
params.insert(param_name.into(), (*loc_segment).into());
} else if segment != loc_segment {
// if any segment doesn't match and isn't a param, there's no path match
return None;
}

if !segment.is_empty() {
path.push('/');
}
path.push_str(loc_segment);
}
}

if let Some(splat) = &self.splat {
if !splat.is_empty() {
let value = if len_diff > 0 {
loc_segments[self.len..].join("/")
} else {
"".into()
};
let mut value = String::new();
_ = loc_segments_iter.next(); // eat the next `/`
for loc_segment in loc_segments_iter {
value.push('/');
value.push_str(loc_segment);
}
params.insert(splat.into(), value);
}
}
Expand Down
15 changes: 15 additions & 0 deletions router/tests/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,20 @@ cfg_if! {
})
);
}

#[test]
fn matcher_should_include_multiple_slashes_in_a_splat_route() {
let matcher = Matcher::new("/*any");
let matched = matcher.test("////");
assert_eq!(
matched,
Some(PathMatch {
path: "".into(),
params: params_map!(
"any" => "///"
)
})
);
}
}
}

0 comments on commit 468e167

Please sign in to comment.