pth 0.37.0

Collection of algorithms and structures to handle paths properly.
Documentation
## 8. Usage Examples

### 8.1 Basic Path Normalization

```rust
use pth::path;

// Remove . and .. components
let clean = path::normalize("/a/./b/../c");
assert_eq!(clean, PathBuf::from("/a/c"));

// Handle relative paths
let clean = path::normalize("../../foo/bar");
assert_eq!(clean, PathBuf::from("../../foo/bar"));

// Empty path becomes .
let clean = path::normalize("");
assert_eq!(clean, PathBuf::from("."));
```

### 8.2 Type-Safe Absolute Paths

```rust
use pth::AbsolutePath;

// Create absolute path
let abs = AbsolutePath::try_from("/home/user/project")?;

// Type system enforces absoluteness
fn requires_absolute(path: AbsolutePath) {
    // Guaranteed not to start with . or ..
    println!("Processing: {}", path.display());
}

requires_absolute(abs);

// Joining preserves type
let subpath = abs.join("src/main.rs");
// subpath is still AbsolutePath
```

### 8.3 Generic Path Functions

```rust
use pth::{AsPath, TryIntoPath};

// Accept various path types
fn process_path<P: TryIntoPath>(path: P) -> io::Result<()> {
    let path = path.try_into_path()?;
    println!("Processing: {}", path.display());
    Ok(())
}

// Works with all of these:
process_path("relative/path")?;
process_path(PathBuf::from("/absolute/path"))?;
process_path(&some_path_variable)?;
process_path(CurrentPath)?; // Resolves to current_dir()
```

### 8.4 Extension Manipulation

```rust
use pth::path;

// Get all extensions
let exts = path::exts("archive.tar.gz");
assert_eq!(exts, vec!["tar".to_string(), "gz".to_string()]);

// Get single extension
let ext = path::ext("file.txt");
assert_eq!(ext, "txt");

// Remove extension
let without = path::without_ext("file.txt").unwrap();
assert_eq!(without, PathBuf::from("file"));

// Change extension
let changed = path::change_ext("file.txt", "json").unwrap();
assert_eq!(changed, PathBuf::from("file.json"));
```

### 8.5 Path Joining with Absolute Reset

```rust
use pth::path;

// Regular joining
let result = path::iter_join(vec!["base", "sub", "file.txt"].into_iter());
assert_eq!(result, PathBuf::from("base/sub/file.txt"));

// Absolute path resets
let result = path::iter_join(vec!["base", "/absolute", "file.txt"].into_iter());
assert_eq!(result, PathBuf::from("/absolute/file.txt"));
// "base" was discarded when "/absolute" was encountered
```

### 8.6 Relative Path Computation

```rust
use pth::path;

// Compute relative path
let rel = path::path_relative("/home/user/project", "/home/user/docs/file.txt");
assert_eq!(rel, PathBuf::from("../../docs/file.txt"));

// Same directory
let rel = path::path_relative("/a/b", "/a/b");
assert_eq!(rel, PathBuf::from("."));

// Child directory
let rel = path::path_relative("/a/b", "/a/b/c/d");
assert_eq!(rel, PathBuf::from("c/d"));
```

### 8.7 Path Rebasing

```rust
use pth::path;

// Move file from old base to new base
let rebased = path::rebase(
    "/project/old/src/main.rs",
    "/project/new",
    Some("/project/old")
)?;
assert_eq!(rebased, PathBuf::from("/project/new/src/main.rs"));

// Without old_path, uses common prefix
let rebased = path::rebase(
    "/project/src/main.rs",
    "/new/location",
    None
)?;
```

---