pinapod 0.3.3

Zero-copy pod types with derive macros. Alignment-1 representations for zero-overhead data access.
Documentation
# PinaPod

PinaPod defines alignment-one, zero-copy representations for Solana account and instruction data. The derive generates the representation, validates bytes before forming references, and keeps the v0.1 wire format.

PinaPod is the Pina-maintained fork of [ZeroPod](https://github.com/blueshift-gg/zeropod). The crates have independent versions. PinaPod reviews upstream changes before porting them.

## Install

```toml
[dependencies]
pinapod = "0.2"
```

PinaPod supports Rust 1.89 and newer. The MSRV follows the Rust versions supported by Solana's Agave releases; see the [supported toolchains page](https://pina-rs.github.io/pinapod/support.html) for the current alignment and policy. The runtime crate is `no_std`.

## Pick a layout

Use a fixed layout when the account allocation never changes. Bounded strings, vectors, and options work in fixed layouts. Their full capacities occupy account bytes.

```rust
use pinapod::{PinaPod, String, Vec};

#[derive(PinaPod)]
struct Profile {
	authority: [u8; 32],
	display_name: String<32>,
	roles: Vec<u16, 8>,
	note: Option<String<64>>,
}

let mut data = vec![0_u8; Profile::SIZE];
Profile::initialize(&mut data, |profile| {
	profile.display_name.try_set("ifi")?;
	profile.roles.try_set([7_u16, 11])?;
	Ok(())
})?;

let profile = Profile::read_exact(&data)?;
assert_eq!(profile.display_name.as_str(), "ifi");
# Ok::<(), pinapod::PinaPodError>(())
```

Use a compact layout when the allocation must track active data. Compact schemas store fixed fields in a header and pack active string and vector bytes after that header.

```rust
use pinapod::{PinaPod, String, Vec};

#[derive(PinaPod)]
#[pinapod(compact)]
struct Journal {
    authority: [u8; 32],
    revision: u64,
    entries: Vec<u64, 1024>,
    note: Option<String<128>>,
}
```

Compact schemas support multiple tails. See the [compact account guide](https://pina-rs.github.io/pinapod/compact-accounts.html) for the supported grammar and update API.

## Set a prefix width in the type

The schema aliases choose common prefix widths:

- `String<N>` is `PodString<N, 1>`.
- `Vec<T, N>` is `PodVec<T, N, 2>`.

Use the pod types when the wire format needs another width. `PFX` is the number of prefix bytes and must be `1`, `2`, `4`, or `8`.

```rust
use pinapod::{PinaPod, PodString, PodVec};

#[derive(PinaPod)]
struct Archive {
    label: PodString<300, 2>,
    values: PodVec<u64, 1024, 2>,
}
```

Do not use `#[pinapod(prefix = u16)]`. Prefix width belongs in the field type, so the declaration shows the exact wire representation.

## Pod types

| Type                       |                     Stored size | Meaning                                     |
| -------------------------- | ------------------------------: | ------------------------------------------- |
| `PodU16` through `PodU128` |              2 through 16 bytes | Unsigned, little-endian integer             |
| `PodI16` through `PodI128` |              2 through 16 bytes | Signed, little-endian integer               |
| `PodBool`                  |                          1 byte | Boolean with a `0` or `1` byte              |
| `PodF32`                   |                         4 bytes | IEEE-754 binary32 stored as its bit pattern |
| `PodF64`                   |                         8 bytes | IEEE-754 binary64 stored as its bit pattern |
| `PodOption<T, PFX>`        |          `PFX + size_of::<T>()` | Optional fixed representation               |
| `PodString<N, PFX>`        |                       `PFX + N` | UTF-8 string with at most `N` bytes         |
| `PodVec<T, N, PFX>`        | `PFX + N * mapped element size` | Vector with at most `N` mapped pod elements |

All representations have alignment one. Safe readers validate tags, lengths, UTF-8, enum discriminants, nested values, and slice bounds before they return a reference.

## Features

| Feature                | Adds                                                     |
| ---------------------- | -------------------------------------------------------- |
| `fixed`                | Mappings for signed and unsigned `fixed` 1.30.0 values   |
| `floats`               | `PodF32`/`PodF64` and mappings for native `f32`/`f64`    |
| `solana-address`       | A mapping for `solana_address::Address`                  |
| `solana-program-error` | Conversion from `PinaPodError` to `ProgramError`         |
| `wincode`              | Canonical `SchemaRead` and `SchemaWrite` implementations |

## Documentation and verification

The [PinaPod book](https://pina-rs.github.io/pinapod/) contains the API guide, the migration guides ([v0.1 to v0.2](https://pina-rs.github.io/pinapod/migration-v0.2.html) and [v0.2 to v0.3](https://pina-rs.github.io/pinapod/migration-v0.3.html)), the safety model, and benchmark instructions. The repository runs native tests on the pinned nightly, current stable, and the MSRV; Miri regressions; Kani proofs including derive-generated compact schemas; coverage-guided fuzzing over every untrusted-input reader (see [fuzz/README.md](fuzz/README.md)); wire-format fixtures; and a Criterion comparison against both PinaPod v0.1 and upstream ZeroPod. Versions and changelogs are managed by MonoChange, which also provides the semantic-version compatibility check for each release.

Report a suspected soundness or security defect through GitHub private vulnerability reporting. See [SECURITY.md](SECURITY.md) for the required report details.

## License

Apache-2.0