smart-string 0.3.0

A collection of string types and traits designed for enhanced string manipulation.
Documentation
# `PascalString` ↔ `std::string::String` parity table

Legend:

- **Match**:
  - βœ… = full correspondence is possible (same semantics are achievable for a fixed-capacity string)
  - 🚫 = full correspondence is not possible (due to fixed capacity, lack of owned buffer, or fundamentally different safety model)
- **Implemented**:
  - βœ… = exists
  - 🟑 = partial (some equivalent exists, but semantics/API differ)
  - ❌ = not implemented

Notes:

- `PascalString` is **fixed capacity**, so many `String` β€œinfallible growth” methods cannot have true parity.
- For those, we prefer **non-panicking `try_*` APIs** plus **`*_truncated`** (returning remainder) and explicit panicking
  **`*_expect_capacity`** variants.

| `String` method | Match | PascalString method (full match) | Additional / alternative methods | Implemented |
|---|---:|---|---|---:|
| `as_bytes` | βœ… | `as_bytes` | `as_ref::<[u8]>()` | βœ… |
| `as_mut_str` | βœ… | `as_mut_str` | *(also `DerefMut<Target=str>` provides `&mut str`)* | βœ… |
| `as_mut_vec` | 🚫 | β€” | *(would expose raw bytes and break UTF‑8 invariant unless heavily constrained / unsafe)* | ❌ |
| `as_str` | βœ… | `as_str` | *(also `Deref<Target=str>`)* | βœ… |
| `capacity` | βœ… | `capacity` | `CAPACITY` const (via type parameter) | βœ… |
| `clear` | βœ… | `clear` | β€” | βœ… |
| `drain` | 🚫 | β€” | *(could be emulated by copying into a new buffer; return type/lifetime makes parity awkward)* | ❌ |
| `extend_from_within` | 🚫 | β€” | *(could be provided as `try_extend_from_within` / `*_truncated` / `*_expect_capacity`)* | ❌ |
| `from_raw_parts` | 🚫 | β€” | `into_inner` (different) | ❌ |
| `from_utf16` | 🚫 | β€” | *(could be `try_from_utf16` β†’ `Result<PascalString, TooLong/DecodeError>`)* | ❌ |
| `from_utf16_lossy` | 🚫 | β€” | *(could be `from_utf16_lossy_truncated` / `try_from_utf16_lossy`)* | ❌ |
| `from_utf16be` | 🚫 | β€” | β€” | ❌ |
| `from_utf16be_lossy` | 🚫 | β€” | β€” | ❌ |
| `from_utf16le` | 🚫 | β€” | β€” | ❌ |
| `from_utf16le_lossy` | 🚫 | β€” | β€” | ❌ |
| `from_utf8` | 🚫 | β€” | `TryFrom<&[u8]> for PascalString` (validates UTF‑8 + capacity) | 🟑 |
| `from_utf8_lossy` | 🚫 | β€” | `from_str_truncated` + caller-side `String::from_utf8_lossy` | ❌ |
| `from_utf8_lossy_owned` | 🚫 | β€” | β€” | ❌ |
| `from_utf8_unchecked` | 🚫 | β€” | *(not applicable without owned heap buffer; `PascalString` maintains UTF‑8 invariant by construction)* | ❌ |
| `insert` | 🚫 | β€” | `try_insert`, `insert_expect_capacity` | 🟑 |
| `insert_str` | 🚫 | β€” | `try_insert_str`, `insert_str_expect_capacity` | 🟑 |
| `into_boxed_str` | 🚫 | β€” | `to_string().into_boxed_str()` | ❌ |
| `into_bytes` | 🚫 | β€” | `as_bytes().to_vec()`; `into_inner()` (bytes+len) | 🟑 |
| `into_chars` | 🚫 | β€” | *(iterate chars via `chars()` on `&str`)* | ❌ |
| `into_raw_parts` | 🚫 | β€” | `into_inner` (len + inline array) | 🟑 |
| `is_empty` | βœ… | `is_empty` | β€” | βœ… |
| `leak` | 🚫 | β€” | β€” | ❌ |
| `len` | βœ… | `len` | β€” | βœ… |
| `new` | βœ… | `new` | β€” | βœ… |
| `pop` | βœ… | `pop` | β€” | βœ… |
| `push` | 🚫 | β€” | `try_push`, `push_expect_capacity`, `push_str_truncated` (for strings) | 🟑 |
| `push_str` | 🚫 | β€” | `try_push_str`, `push_str_truncated`, `push_str_expect_capacity` | 🟑 |
| `remove` | βœ… | `remove` *(panicking on invalid idx/boundary like `String`)* | `try_remove` (non-panicking) | 🟑 |
| `remove_matches` | 🚫 | β€” | `remove_matches(&str)` *(in-place scan+compact; `retain` covers char-level filtering)* | 🟑 |
| `replace_first` | 🚫 | β€” | *(could be implemented on `&str` output; may need truncation APIs)* | ❌ |
| `replace_last` | 🚫 | β€” | β€” | ❌ |
| `replace_range` | 🚫 | β€” | `try_replace_range_bounds`, `try_replace_range_bounds_truncated`, `replace_range_bounds_expect_capacity` | 🟑 |
| `reserve` | 🚫 | β€” | *(no-op if within capacity; otherwise cannot)* | ❌ |
| `reserve_exact` | 🚫 | β€” | β€” | ❌ |
| `retain` | βœ… | `retain` | β€” | βœ… |
| `shrink_to` | 🚫 | β€” | *(no-op for fixed-capacity)* | ❌ |
| `shrink_to_fit` | 🚫 | β€” | *(no-op for fixed-capacity)* | ❌ |
| `split_off` | 🚫 | β€” | `split_off(at)` panicking + `try_split_off(at)` non-panicking | 🟑 |
| `truncate` | βœ… | `truncate` *(requires char boundary, panics like `String` on invalid boundary)* | β€” | βœ… |
| `try_reserve` | 🚫 | β€” | *(could return Ok if fits, Err otherwise; not present)* | ❌ |
| `try_reserve_exact` | 🚫 | β€” | β€” | ❌ |
| `try_with_capacity` | 🚫 | β€” | `new` (capacity is const), `try_from_str_const` (const ctx) | ❌ |
| `with_capacity` | 🚫 | β€” | `new` (capacity is const) | ❌ |