laminar-derive 0.18.5

Derive macros for LaminarDB Record and FromRecordBatch traits
Documentation
# laminar-derive

Derive macros for LaminarDB -- `Record`, `FromRecordBatch`, `FromRow`, and `ConnectorConfig`.

## Overview

Procedural macros for Arrow RecordBatch conversion and connector config parsing. Eliminates the boilerplate of writing `to_record_batch()` / `from_batch()` by hand.

## Macros

### `#[derive(Record)]`

Generates `Record::schema()`, `Record::to_record_batch()`, and `Record::event_time()` for typed data ingestion.

```rust
use laminar_derive::Record;

#[derive(Record)]
struct Trade {
    symbol: String,
    price: f64,
    volume: i64,
    #[event_time]
    ts: i64,
}
```

**Attributes:**
- `#[event_time]` -- marks a field as the event time column
- `#[column("name")]` -- overrides the Arrow column name
- `#[nullable]` -- marks a non-Option field as nullable in the schema

**Supported types:** `bool`, `i8`-`i64`, `u8`-`u64`, `f32`, `f64`, `String`, `Vec<u8>`, `Option<T>`

### `#[derive(FromRecordBatch)]`

Generates `from_batch()` and `from_batch_all()` for deserializing Arrow RecordBatches into typed structs. Fields are matched by name.

```rust
use laminar_derive::FromRecordBatch;

#[derive(FromRecordBatch)]
struct OhlcBar {
    symbol: String,
    open: f64,
    high: f64,
    low: f64,
    close: f64,
}
```

### `#[derive(FromRow)]`

Like `FromRecordBatch`, but also implements `laminar_db::FromBatch`. Fields are matched by **position** (column order in SELECT), not by name.

```rust
use laminar_derive::FromRow;

#[derive(FromRow)]
struct Result {
    symbol: String,    // 1st SELECT column
    total: i64,        // 2nd SELECT column
    avg_price: f64,    // 3rd SELECT column
}
```

### `#[derive(ConnectorConfig)]`

Generates `from_config()`, `validate()`, and `config_keys()` for connector configuration parsing.

```rust
use laminar_derive::ConnectorConfig;

#[derive(ConnectorConfig)]
struct MySourceConfig {
    #[config(key = "bootstrap.servers", required, description = "Kafka brokers")]
    bootstrap_servers: String,

    #[config(key = "batch.size", default = "1000")]
    batch_size: usize,

    #[config(key = "timeout.ms", default = "30000", duration_ms)]
    timeout: std::time::Duration,

    #[config(key = "api.key", env = "MY_API_KEY")]
    api_key: Option<String>,
}
```

**Attributes:**
- `#[config(key = "...")]` -- config key name
- `#[config(required)]` -- field is required
- `#[config(default = "...")]` -- default value
- `#[config(env = "...")]` -- environment variable fallback
- `#[config(description = "...")]` -- documentation for the key
- `#[config(duration_ms)]` -- parse as `Duration` from milliseconds

## Related Crates

- [`laminar-core`]../laminar-core -- `Record` trait definition
- [`laminar-db`]../laminar-db -- `TypedSubscription<T>` and `SourceHandle<T>` that use derived traits
- [`laminar-connectors`]../laminar-connectors -- Connector SDK that uses `ConnectorConfig`