Skip to content

Commit f2dd094

Browse files
committed
chore: polish README.md
1 parent c7628c9 commit f2dd094

File tree

1 file changed

+90
-37
lines changed

1 file changed

+90
-37
lines changed

README.md

Lines changed: 90 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,127 @@
11
# sugar_path
22

3-
[![document](https://docs.rs/sugar_path/badge.svg)](https://docs.rs/sugar_path/latest/sugar_path/)
4-
[![crate version](https://img.shields.io/crates/v/sugar_path.svg)](https://crates.io/crates/sugar_path)
3+
[![docs.rs](https://docs.rs/sugar_path/badge.svg)](https://docs.rs/sugar_path/latest/sugar_path/)
4+
[![crates.io](https://img.shields.io/crates/v/sugar_path.svg)](https://crates.io/crates/sugar_path)
55
[![MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
66

7-
Sugar functions for manipulating paths.
7+
Ergonomic path manipulation for Rust — normalize, absolutize, relativize, and slash-convert with zero-cost `Cow` returns.
88

9-
- [Documents](https://docs.rs/sugar_path/latest/sugar_path/)
9+
## Quick start
1010

11-
## Main functionalities
12-
13-
- [SugarPath::as_path](https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.as_path) makes it easy to convert `T: Deref<Target = str>` to `Path` and allows you to use methods of `SugarPath` on `&str` or `String` directly.
11+
```bash
12+
cargo add sugar_path
13+
```
1414

1515
```rust
16-
use std::path::Path;
1716
use sugar_path::SugarPath;
18-
assert_eq!("foo".as_path().join("bar"), Path::new("foo/bar"));
17+
18+
// Normalize messy paths
1919
assert_eq!("foo/./bar/../baz".normalize(), "foo/baz".as_path());
20-
```
2120

22-
- [SugarPath::to_slash](https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.to_slash)/[SugarPath::to_slash_lossy](https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.to_slash_lossy) allows you to convert the path to the string with consistent slash separator on all platforms.
21+
// Absolutize relative paths
22+
let abs = "src/main.rs".absolutize();
2323

24-
```rust
25-
use sugar_path::SugarPath;
26-
#[cfg(target_family = "unix")]
27-
let p = "./hello/world".as_path();
28-
#[cfg(target_family = "windows")]
29-
let p = ".\\hello\\world".as_path();
30-
assert_eq!(p.to_slash().unwrap(), "./hello/world");
31-
assert_eq!(p.to_slash_lossy(), "./hello/world");
24+
// Get relative paths between two locations
25+
assert_eq!("/a/b/c/d".as_path().relative("/a/b/f/g"), "../../c/d".as_path());
26+
27+
// Cross-platform slash conversion
28+
assert_eq!("hello/world".as_path().to_slash_lossy(), "hello/world");
3229
```
3330

34-
- [SugarPath::normalize](https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.normalize) allows you normalize given path by dropping unnecessary `.` or `..` segments.
31+
## API overview
32+
33+
All methods are provided by the `SugarPath` trait, implemented for `Path`, `&str`, and `String`.
34+
35+
### Path conversion
36+
37+
| Method | Description |
38+
|--------|-------------|
39+
| [`as_path()`] | Convert `&str` / `String` to `&Path` — lets you call `SugarPath` methods on strings directly |
40+
| [`to_slash()`] | Convert a path to a `/`-separated string (`None` if invalid UTF-8) |
41+
| [`to_slash_lossy()`] | Like `to_slash()`, but replaces invalid UTF-8 with `U+FFFD` |
3542

3643
```rust
3744
use std::path::Path;
3845
use sugar_path::SugarPath;
39-
assert_eq!("foo/./bar/../baz".normalize(), "foo/baz".as_path());
46+
47+
assert_eq!("foo".as_path().join("bar"), Path::new("foo/bar"));
4048
```
4149

42-
- [SugarPath::relative](https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.relative) allows you to get the relative path from the given path to the target path.
50+
[`as_path()`]: https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.as_path
51+
[`to_slash()`]: https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.to_slash
52+
[`to_slash_lossy()`]: https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.to_slash_lossy
4353

44-
```rust
45-
use sugar_path::SugarPath;
46-
assert_eq!("/base".relative("/base/project"), "..".as_path());
47-
assert_eq!("/base".relative("/var/lib"), "../../base".as_path());
48-
```
54+
### Normalization
4955

50-
- [SugarPath::absolutize](https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.absolutize) is a shortcut of [SugarPath::absolutize_with](https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.absolutize_with) with passing `std::env::current_dir().unwrap()` as the base path.
56+
[`normalize()`] resolves `.` and `..` segments and collapses repeated separators. Returns `Cow::Borrowed` when the path is already clean.
5157

5258
```rust
59+
use std::path::Path;
5360
use sugar_path::SugarPath;
54-
let cwd = std::env::current_dir().unwrap();
55-
assert_eq!("hello/world".absolutize(), cwd.join("hello").join("world"));
61+
62+
#[cfg(target_family = "unix")]
63+
assert_eq!(
64+
Path::new("/foo/bar//baz/asdf/quux/..").normalize(),
65+
Path::new("/foo/bar/baz/asdf")
66+
);
5667
```
5768

58-
- [SugarPath::absolutize_with](https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.absolutize_with) allows you to absolutize the given path with the base path.
69+
[`normalize()`]: https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.normalize
70+
71+
### Absolutize
72+
73+
[`absolutize()`] resolves a relative path against the current working directory. [`absolutize_with()`] lets you supply a custom base.
5974

6075
```rust
6176
use sugar_path::SugarPath;
77+
6278
#[cfg(target_family = "unix")]
6379
{
6480
assert_eq!("./world".absolutize_with("/hello"), "/hello/world".as_path());
6581
assert_eq!("../world".absolutize_with("/hello"), "/world".as_path());
6682
}
67-
#[cfg(target_family = "windows")]
68-
{
69-
assert_eq!(".\\world".absolutize_with("C:\\hello"), "C:\\hello\\world".as_path());
70-
assert_eq!("..\\world".absolutize_with("C:\\hello"), "C:\\world".as_path());
71-
}
7283
```
7384

74-
- For more details, please refer to the [SugarPath](https://docs.rs/sugar_path/latest/sugar_path/index.html).
85+
[`absolutize()`]: https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.absolutize
86+
[`absolutize_with()`]: https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.absolutize_with
87+
88+
### Relative paths
89+
90+
[`relative()`] computes the relative path from `self` to a target.
91+
92+
```rust
93+
use std::path::Path;
94+
use sugar_path::SugarPath;
95+
96+
assert_eq!(Path::new("/base").relative("/base/lib"), Path::new(".."));
97+
assert_eq!(Path::new("/base").relative("/var/lib"), Path::new("../../base"));
98+
assert_eq!(Path::new("/a/b/c/d").relative("/a/b/f/g"), Path::new("../../c/d"));
99+
```
100+
101+
[`relative()`]: https://docs.rs/sugar_path/latest/sugar_path/trait.SugarPath.html#tymethod.relative
102+
103+
## Features
104+
105+
| Feature | Description |
106+
|---------|-------------|
107+
| `cached_current_dir` | Cache `std::env::current_dir()` so `absolutize()` only reads it once |
108+
109+
```toml
110+
sugar_path = { version = "2", features = ["cached_current_dir"] }
111+
```
112+
113+
## Performance
114+
115+
- **Zero-alloc fast paths** — methods return `Cow<'_, Path>`, borrowing the input when no transformation is needed.
116+
- **`memchr`-accelerated scanning** for separator detection.
117+
- **`SmallVec<[_; 8]>`** keeps component lists on the stack for typical path depths.
118+
119+
## Platform support
120+
121+
- Unix and Windows, tested in CI on Ubuntu, macOS, and Windows.
122+
- `to_slash` / `to_slash_lossy` provide consistent `/`-separated output across all platforms.
123+
- On Windows, forward slashes in input are normalized to `\`.
124+
125+
## License
126+
127+
MIT

0 commit comments

Comments
 (0)