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]]
name = "nod"
version = "1.4.0"
version = "1.4.1"
dependencies = [
"adler",
"aes",
@ -464,7 +464,7 @@ dependencies = [
[[package]]
name = "nodtool"
version = "1.4.0"
version = "1.4.1"
dependencies = [
"argp",
"base16ct",

View File

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

View File

@ -130,15 +130,17 @@ impl<'a> Fst<'a> {
#[allow(clippy::missing_inline_in_public_items)]
pub fn find(&self, path: &str) -> Option<(usize, Node)> {
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 stop_at = None;
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 let Some(next) = split.next() {
current = next;
} else {
current = next_non_empty(&mut split);
if current.is_empty() {
return Some((idx, node));
}
// Descend into directory
@ -178,3 +180,14 @@ impl<'a> Iterator for FstIter<'a> {
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 "",
}
}
}