diff --git a/src/node.rs b/src/node.rs index b6131c3..a0320ef 100644 --- a/src/node.rs +++ b/src/node.rs @@ -197,76 +197,6 @@ impl Node { } } Key::Parameter(k) => match k { - // Kind::Normal => { - // if m == 0 { - // return None; - // } - // - // // slash node - // let mut slash = None; - // // slash position at path - // let sp = bytes.iter().position(|b| *b == b'/'); - // - // // static - // if let Some(id) = self.nodes0.as_ref().and_then(|nodes| { - // let tmp = &bytes[0..sp.unwrap_or(m)]; - // nodes.iter().find_map(|node| match node.key { - // Key::String(s) => { - // if s[0] == b'/' { - // slash.replace(node); - // return None; - // } - // - // tmp.iter().position(|b| s[0] == *b).and_then(|n| { - // node._find(start + n, &bytes[n..], ranges).map(|id| { - // ranges.push(start); - // ranges.push(start + n); - // id - // }) - // }) - // } - // _ => unreachable!(), - // }) - // }) { - // return Some(id); - // } - // - // // parameter => `:a:b:c` - // if let Some(id) = self.nodes1.as_ref().and_then(|nodes| { - // let b = m - 1 > 0; - // nodes - // .iter() - // .filter(|node| match node.key { - // Key::Parameter(pk) - // if pk == Kind::Normal || pk == Kind::OneOrMore => - // { - // b - // } - // _ => true, - // }) - // .find_map(|node| node._find(start + 1, &bytes[1..], ranges)) - // }) { - // ranges.push(start); - // ranges.push(start + 1); - // return Some(id); - // } - // - // if let Some(n) = sp { - // return slash - // .and_then(|node| node._find(start + n, &bytes[n..], ranges)) - // .map(|id| { - // ranges.push(start); - // ranges.push(start + n); - // id - // }); - // } else { - // return self.value.as_ref().map(|id| { - // ranges.push(start); - // ranges.push(start + m); - // id - // }); - // } - // } Kind::Normal | Kind::Optional | Kind::OptionalSegment => { if m == 0 { if k == &Kind::Normal { @@ -285,12 +215,29 @@ impl Node { if let Some(id) = self.nodes0.as_ref().and_then(|nodes| { nodes.iter().find_map(|node| match &node.key { Key::String(s) => { - bytes.iter().position(|b| s[0] == *b).and_then(|n| { - node._find(start + n, &bytes[n..], ranges).map(|id| { - ranges.push(start..start + n); - id + let mut keep_running = true; + bytes + .iter() + // as it turns out doing .copied() here is much slower than dereferencing in the closure + // https://godbolt.org/z/7dnW91T1Y + .take_while(|b| { + if keep_running && **b == b'/' { + keep_running = false; + true + } else { + keep_running + } + }) + .enumerate() + .find_map(|(n, b)| { + if s[0] != *b { + return None; + } + node._find(start + n, &bytes[n..], ranges).map(|id| { + ranges.push(start..start + n); + id + }) }) - }) } Key::Parameter(_) => unreachable!(), }) @@ -396,20 +343,15 @@ impl Node { m >= s.len() }; if right_length { - return bytes - .iter() - .enumerate() - .filter_map( - |(n, b)| if s[0] == *b { Some(n) } else { None }, - ) - .find_map(|n| { - node._find(start + n, &bytes[n..], ranges).map( - |id| { - ranges.push(start..start + n); - id - }, - ) - }); + return bytes.iter().enumerate().find_map(|(n, b)| { + if s[0] != *b { + return None; + } + node._find(start + n, &bytes[n..], ranges).map(|id| { + ranges.push(start..start + n); + id + }) + }); } } None diff --git a/tests/tree.rs b/tests/tree.rs index 16d8fc7..2596381 100644 --- a/tests/tree.rs +++ b/tests/tree.rs @@ -2257,3 +2257,60 @@ fn test_dots_ext() { assert_eq!(params.params(), &[("name", "abc.xyz")]); } + +#[test] +fn test_dots_ext_no_qualifier() { + let mut tree = PathTree::new(); + let _ = tree.insert("/:name.js", 2); + let _ = tree.insert("/:name.js.gz", 1); + + assert_eq!( + format!("{:?}", &tree.node), + r" +/ +└── : + └── .js •0 + └── .gz •1 +" + ); + + let result = tree.find("/node.js"); + assert!(result.is_some()); + + let (value, params) = result.unwrap(); + assert_eq!(value, &2); + + assert_eq!(params.params(), &[("name", "node")]); + + let result = tree.find("/path.lib.js"); + assert!(result.is_some()); + + let (value, params) = result.unwrap(); + assert_eq!(value, &2); + + assert_eq!(params.params(), &[("name", "path.lib")]); + + let result = tree.find("/node.js.js"); + assert!(result.is_some()); + + let (value, params) = result.unwrap(); + assert_eq!(value, &2); + + assert_eq!(params.params(), &[("name", "node.js")]); + + let result = tree.find("/node.js.gz"); + assert!(result.is_some()); + + let (value, params) = result.unwrap(); + assert_eq!(value, &1); + + assert_eq!(params.params(), &[("name", "node")]); + + let result = tree.find("/node.js.gz.js.gz"); + assert!(result.is_some()); + + let (value, params) = result.unwrap(); + assert_eq!(value, &1); + + assert_eq!(params.params(), &[("name", "node.js.gz")]); +}