wingfoil 4.0.1

graph based stream processing framework
Documentation
# CSV Adapter

Reads and writes comma-separated values files as wingfoil streams.

## Module Structure

```
csv/
  mod.rs        # Module-level doc, re-exports from read and write
  read.rs       # csv_read, csv_iterator (pub(super))
  write.rs      # CsvWriterNode, CsvOperators, tests
  test_data/    # CSV fixtures used by unit tests
  CLAUDE.md     # This file
```

## Key Components

### Reading — `csv_read`

- `csv_read(path, get_time_func, has_headers)` — emits `Burst<T>` per tick; multiple rows with the same timestamp are grouped into a single burst (uses `IteratorStream`)
- Delegates to the private `csv_iterator` which deserialises rows via `serde`

### Writing — `CsvOperators`

- `.csv_write(path)` — fluent method on both `Rc<dyn Stream<Burst<T>>>` and `Rc<dyn Stream<T>>`; writes one row per element per tick with a leading `time` column
- Single-value streams are auto-wrapped into a one-element burst

Headers are written lazily on first tick using `serde_aux::serde_introspection::serde_introspect`.

### `IteratorStream` / `SimpleIteratorStream`

These general-purpose nodes live in `crate::nodes` (not the adapters layer).
The CSV adapter imports them directly; they are also available via `wingfoil::*`.

## Test Data

Unit tests live in `write.rs` and use files under `src/adapters/csv/test_data/`
(paths are relative to the package root `wingfoil/`, which is Cargo's cwd when running tests).

## Pre-Commit Requirements

```bash
cargo fmt --all
cargo clippy --workspace --all-targets --all-features
cargo test -p wingfoil
```