Fast POSIX-style path join and normalize using / as the only separator.
Mirrors the semantics of Node.js path.posix.join and path.posix.normalize:
- Resolves
.and..segments - Collapses consecutive
/into one - Preserves a single trailing
/when the input has one - Empty input normalizes to
"." - Backslashes (
\) are treated as literal characters, not separators
use path_posix::{normalize, join};
assert_eq!(normalize("/a/b/../c"), "/a/c");
assert_eq!(normalize("a//b/./c"), "a/b/c");
assert_eq!(join(&["/foo", "bar", "baz/asdf", "quux", ".."]), "/foo/bar/baz/asdf");
assert_eq!(join(&["a", "/b", "c"]), "a/b/c");Both functions return Cow<str> — zero allocation when the input is already
clean (normalize) or when all segments are empty (join).
| Input | Time |
|---|---|
"" (empty) |
~1 ns |
/ (root) |
~2 ns |
/a/b/c (fast path, already clean) |
~4 ns |
/a/b/c/ (fast path, trailing slash) |
~5 ns |
/usr/local/.../npm-cli.js (fast path, long) |
~19 ns |
/a/b/../c (dots) |
~31 ns |
/a/b/c/d/../../e/f/./g/../h (deep dots) |
~66 ns |
/a/./b/../c//d/./e/../f/g/../../h (mixed) |
~77 ns |
| Input | Time |
|---|---|
| 2 segments | ~31 ns |
2 segments with .. |
~31 ns |
| 3 segments | ~29 ns |
8 segments with .. |
~53 ns |
Measured on Apple M4 Pro with cargo bench. See benches/ for details.
- Node.js
path.posix— semantics reference and test cases - sugar_path —
needs_normalizationfast-path detection,memchr/memrchrscanning techniques, andNormalizeStatebuffer architecture
MIT