# Zero-Copy Decoding
For maximum performance, `zero-mysql` provides zero-copy row decoding through the `RefFromRow` trait. This allows you to decode rows as references directly into the read buffer, avoiding any memory allocation or copying.
## When to Use
Zero-copy decoding is useful when:
- Processing large result sets where allocation overhead matters
- All columns are fixed-size types (integers, floats)
- All columns are `NOT NULL`
- You don't need to store the decoded rows (processing in a callback)
## Requirements
To use zero-copy decoding, your struct must:
1. Derive `RefFromRow`
2. Have `#[repr(C, packed)]` attribute
3. Use little-endian types from `zerocopy` (MySQL uses little-endian wire format)
## Example
```rust
use zero_mysql::ref_row::{RefFromRow, I64LE, I32LE};
use zero_mysql_derive::RefFromRow;
#[derive(RefFromRow)]
#[repr(C, packed)]
struct UserStats {
user_id: I64LE, // 8 bytes
login_count: I32LE, // 4 bytes
}
// Process rows without allocation
## Limitations
- **No NULL support**: All columns must be `NOT NULL`. Use `FromRow` for nullable columns.
- **Fixed-size types only**: Variable-length types like `VARCHAR`, `TEXT`, `BLOB` are not supported.
- **No column name matching**: Columns must match struct field order exactly.
- **Callback-based only**: Returns references into the buffer, so can only be used with `exec_foreach_ref`.
## Comparison with FromRow
| Allocation | Yes (per row) | No |
| NULL support | Yes (`Option<T>`) | No |
| Variable-length types | Yes | No |
| Column name matching | Yes | No |
| Return type | Owned `T` | Reference `&T` |
| API | `exec_first`, `exec_collect`, `exec_foreach` | `exec_foreach_ref` |
## How It Works
1. The derive macro generates `zerocopy` trait implementations (`FromBytes`, `KnownLayout`, `Immutable`)
2. At compile time, it verifies all fields implement `FixedWireSize`
3. At runtime, the row buffer is cast directly to `&YourStruct` using zerocopy
4. No parsing, no allocation - just a pointer cast with size validation