# Trimming and Translating

> StringZilla for Rust

The crate provides byte-level buffer transforms, lookup-table translation, in-place replacement, and Unicode case folding / normalization.

### Lookup Table Translation

`lookup` maps every byte of a source through a 256-entry table into a target, while `lookup_inplace` rewrites a buffer in place.

```rust
pub fn lookup<T: AsMut<[u8]>, S: AsRef<[u8]>>(target: &mut T, source: &S, table: [u8; 256]) -> Result<(), Status>;
pub fn lookup_inplace<T: AsMut<[u8]>>(buffer: &mut T, table: [u8; 256]);
```

`lookup` maps every byte through a 256-entry table; for example to lowercase ASCII:

```rust
use stringzilla as sz;

let mut to_lower: [u8; 256] = core::array::from_fn(|i| i as u8);
for (upper, lower) in ('A'..='Z').zip('a'..='z') {
    to_lower[upper as usize] = lower as u8;
}
let mut text = *b"HELLO WORLD!";
sz::lookup_inplace(&mut text, to_lower);
assert_eq!(&text, b"hello world!");
```

`lookup` returns `Status::UnexpectedDimensions`, writing nothing, when the target is shorter than the source.

### In Place Replacement

These rewrite a `Vec<u8>` in place, replacing either a literal needle or any byte from a `Byteset` with a replacement slice.

```rust
pub fn replace_all(buffer: &mut Vec<u8>, needle: &[u8], replacement: &[u8]) -> Result<usize, Status>;
pub fn replace_all_byteset(buffer: &mut Vec<u8>, byteset: Byteset, replacement: &[u8]) -> Result<usize, Status>;
```

Both replace all non-overlapping occurrences in place, returning the replacement count.
Equal-length replacements overwrite, shorter ones compact forward without allocating, and longer ones resize once and rewrite from the back:

```rust
use stringzilla::{self as sz, Byteset};

let mut buffer = b"a-b-c".to_vec();
let n = sz::replace_all(&mut buffer, b"-", b"__").unwrap();
assert_eq!(n, 2);
assert_eq!(buffer, b"a__b__c");

let mut spaced = b"a, b ,c".to_vec();
sz::replace_all_byteset(&mut spaced, Byteset::from(", "), b"").unwrap();
assert_eq!(spaced, b"abc");
```

`use stringzilla::*;`

## lookup

Performs a lookup-table transformation, mapping contents of a buffer into the same or other memory region, taking a byte substitution value from the provided table.

```rust
pub fn lookup<Target, Source>(
    target: &mut Target,
    source: &Source,
    table: [u8; 256],
) -> Result<(), Status>
where
    Target: AsMut<[u8]> + ?Sized,
    Source: AsRef<[u8]> + ?Sized,
```

Arguments: - `target`: A mutable buffer to populate.

- `source`: An immutable buffer to map from.

- `table`: Lookup table of 256 substitution values.

Returns [`Status::UnexpectedDimensions`](https://www.unum.cloud/docs/stringzilla/rust/types.md#UnexpectedDimensions) if `target` is shorter than `source`.

Examples: To convert uppercase ASCII characters to lowercase:

```
use stringzilla as sz;
let mut to_lower: [u8; 256] = core::array::from_fn(|i| i as u8);
for (upper, lower) in ('A'..='Z').zip('a'..='z') {
    to_lower[upper as usize] = lower as u8;
}
let source = "HELLO WORLD!";
let mut target = vec![0u8; source.len()];
sz::lookup(&#x26;mut target, &#x26;source, to_lower).unwrap();
let result = String::from_utf8(target).expect("Invalid UTF-8 sequence");
assert_eq!(result, "hello world!");
```

## lookup_inplace

Performs a lookup-table transformation, mapping contents of a buffer into the same or other memory region, taking a byte substitution value from the provided table.

```rust
pub fn lookup_inplace<Buffer>(buffer: &mut Buffer, table: [u8; 256])
where
    Buffer: AsMut<[u8]> + ?Sized,
```

Arguments: - `buffer`: A mutable buffer to update inplace.

- `table`: Lookup table of 256 substitution values.

Examples: ```
use stringzilla as sz;
let mut to_lower: [u8; 256] = core::array::from_fn(|i| i as u8);
for (upper, lower) in ('A'..='Z').zip('a'..='z') {
    to_lower[upper as usize] = lower as u8;
}
let mut text = *b"HELLO WORLD!";
sz::lookup_inplace(&#x26;mut text, to_lower);
assert_eq!(text, *b"hello world!");
```

## replace_all

Replaces all non-overlapping occurrences of `needle` inside `buffer` in place.

```rust
pub fn replace_all(buffer: &mut Vec<u8>, needle: &[u8], replacement: &[u8]) -> Result<usize, Status>
```

- equal-length replacements simply overwrite matches,

- shorter replacements compact forward without allocating,

- longer replacements count matches once, resize once, and rewrite from the back.

Returns the number of replacements performed.

## replace_all_byteset

Replaces all non-overlapping bytes in `buffer` that belong to `byteset` with `replacement`.

```rust
pub fn replace_all_byteset(
    buffer: &mut Vec<u8>,
    byteset: Byteset,
    replacement: &[u8],
) -> Result<usize, Status>
```

Uses the same three-way strategy as [`replace_all`](#replace_all). If the byteset is empty, the buffer is
left untouched. Returns the number of replacements performed.

