stream-rs 0.1.0

Zero-dependency, spec-compliant streaming toolkit for LLM responses (SSE, incremental JSON, OpenAI/Anthropic delta accumulators).
Documentation
# Contributing to stream-rs

Thanks for your interest in improving `stream-rs`. This is a small, focused
crate: the low-level plumbing that turns a raw byte stream into usable LLM
values. Contributions that keep it correct, spec-compliant, and dependency-free
are very welcome.

## Ground rules

- **Zero core dependencies.** The default build must not add runtime
  dependencies. Anything optional goes behind a Cargo feature (as `stream` does
  with `futures-core`).
- **Spec first.** The SSE parser follows the
  [WHATWG event-stream algorithm]https://html.spec.whatwg.org/multipage/server-sent-events.html.
  Behaviour changes that diverge from the spec need a clear rationale.
- **Chunk-boundary invariance.** Any incremental parser change must preserve the
  core property: *the same input split at any byte boundary yields identical
  output*. This is asserted by tests and by the fuzz targets.
- **Document public items.** `missing_docs` is a warning and CI treats warnings
  as errors, so every public item needs a doc comment.

## Local checks (what CI runs)

Before opening a PR, run the same checks CI enforces:

```sh
# Format (CI runs --check)
cargo fmt --all

# Lint: clippy with pedantic lints, warnings as errors
cargo clippy --all-features --all-targets -- -D warnings

# Tests, including doctests, across all features
cargo test --all-features

# Make sure the examples still reassemble their streams correctly
cargo run --example openai_stream
cargo run --example anthropic_stream
cargo run --example gemini_stream

# Minimum supported Rust version (the crate targets 1.70)
# rustup toolchain install 1.70
cargo +1.70 build --all-features
```

### Benchmarks

```sh
cargo bench
```

Criterion reports MB/s for both a single bulk `feed` and realistic 64-byte
ragged chunks.

### Fuzzing

The fuzz crate lives in `fuzz/` and needs nightly + `cargo-fuzz`:

```sh
cargo install cargo-fuzz --locked
cargo +nightly fuzz run sse_parser
cargo +nightly fuzz run json_splitter
```

Each target asserts that arbitrary input never panics and that splitting the
input at a fuzzer-chosen point produces the same output as feeding it whole.

## Adding a provider accumulator

Accumulators live in `src/accumulators/`. They are deliberately JSON-library
agnostic: they accept already-parsed primitive pieces and fold them into the
final value. When adding one:

1. Add `src/accumulators/<provider>.rs` with a doc comment, a runnable doctest,
   and `#[must_use]` on constructors/getters where appropriate.
2. Register it in `src/accumulators/mod.rs`.
3. Add tests to `tests/accumulators.rs`.
4. Add a runnable, no-network example to `examples/`.
5. Add a row to the feature table in `README.md` and a note to `CHANGELOG.md`.

## Commit / PR conventions

- Keep PRs focused; one logical change per PR where possible.
- Update `CHANGELOG.md` under `## [Unreleased]`.
- Make sure `cargo fmt`, `clippy`, and `cargo test --all-features` are clean.

## License

By contributing you agree that your contributions are licensed under the MIT
license, the same as the rest of the project.