Fix matching paths with repeated slashes in Fst::find

This commit is contained in:
Luke Street 2024-10-04 17:25:07 -06:00
parent e6a3871d28
commit d99ef72fe9
3 changed files with 20 additions and 7 deletions

4
Cargo.lock generated
View File

@ -441,7 +441,7 @@ dependencies = [
[[package]] [[package]]
name = "nod" name = "nod"
version = "1.4.0" version = "1.4.1"
dependencies = [ dependencies = [
"adler", "adler",
"aes", "aes",
@ -464,7 +464,7 @@ dependencies = [
[[package]] [[package]]
name = "nodtool" name = "nodtool"
version = "1.4.0" version = "1.4.1"
dependencies = [ dependencies = [
"argp", "argp",
"base16ct", "base16ct",

View File

@ -9,7 +9,7 @@ strip = "debuginfo"
codegen-units = 1 codegen-units = 1
[workspace.package] [workspace.package]
version = "1.4.0" version = "1.4.1"
edition = "2021" edition = "2021"
rust-version = "1.74" rust-version = "1.74"
authors = ["Luke Street <luke@street.dev>"] authors = ["Luke Street <luke@street.dev>"]

View File

@ -130,15 +130,17 @@ impl<'a> Fst<'a> {
#[allow(clippy::missing_inline_in_public_items)] #[allow(clippy::missing_inline_in_public_items)]
pub fn find(&self, path: &str) -> Option<(usize, Node)> { pub fn find(&self, path: &str) -> Option<(usize, Node)> {
let mut split = path.trim_matches('/').split('/'); let mut split = path.trim_matches('/').split('/');
let mut current = split.next()?; let mut current = next_non_empty(&mut split);
if current.is_empty() {
return Some((0, self.nodes[0]));
}
let mut idx = 1; let mut idx = 1;
let mut stop_at = None; let mut stop_at = None;
while let Some(node) = self.nodes.get(idx).copied() { while let Some(node) = self.nodes.get(idx).copied() {
if self.get_name(node).as_ref().map_or(false, |name| name.eq_ignore_ascii_case(current)) if self.get_name(node).as_ref().map_or(false, |name| name.eq_ignore_ascii_case(current))
{ {
if let Some(next) = split.next() { current = next_non_empty(&mut split);
current = next; if current.is_empty() {
} else {
return Some((idx, node)); return Some((idx, node));
} }
// Descend into directory // Descend into directory
@ -178,3 +180,14 @@ impl<'a> Iterator for FstIter<'a> {
Some((idx, node, name)) Some((idx, node, name))
} }
} }
#[inline]
fn next_non_empty<'a>(iter: &mut impl Iterator<Item = &'a str>) -> &'a str {
loop {
match iter.next() {
Some("") => continue,
Some(next) => break next,
None => break "",
}
}
}