1#![forbid(unsafe_code)]
2#![doc = "# nwnrs-key\n\n`nwnrs-key` reads and writes KEY/BIF resource sets, which form the canonical\nindexed storage layout for base-game content.\n\n## Scope\n\n- parse KEY files and their BIF index tables\n- expose the result as a typed [`KeyTable`]\n- implement `nwnrs-resman` container behavior for KEY/BIF-backed content\n- write KEY/BIF output from typed archive state\n\nThe main entry points are [`read_key_table`], [`read_key_table_from_file`], and\n[`write_key_and_bif`].\n\n## Public Surface\n\n- `KeyTable`\n- `KeyBifEntry`\n- `KeyBifContents`\n- `KeyBifVersion`\n- `VariableResource`\n- `BifResolver`\n- `ResId`\n- `KeyError`\n- `KeyResult`\n- `read_key_table`\n- `read_key_table_from_file`\n- `write_key_and_bif`\n- `write_key_table_archive`\n\n## Core Model\n\n- `ResId` is a packed `u32`\n - upper bits identify the owning BIF\n - lower bits identify the variable resource within that BIF\n- `KeyTable` preserves:\n - version\n - label\n - build year and day\n - BIF handles\n - resource-to-id lookup\n - optional OID metadata\n- `VariableResource` preserves:\n - packed id\n - I/O offset\n - stored size\n - compression type\n - uncompressed size\n\n## KEY Layout\n\nHeader size: `64` bytes.\n\nKnown KEY versions:\n\n- `V1`\n- `E1`\n\nHeader shape:\n\n```text\n0x00 \"KEY \"\n0x04 version\n0x08 bif_count u32\n0x0C key_count u32\n0x10 offset_to_file_table u32\n0x14 offset_to_key_table u32\n0x18 build_year u32\n0x1C build_day u32\n0x20 remaining header / OID area\n```\n\nBody:\n\n```text\n+----------------------+\n| KEY header |\n+----------------------+\n| file table | one row per BIF\n+----------------------+\n| filename strings |\n+----------------------+\n| key table | one row per resource\n+----------------------+\n```\n\n## BIF Layout\n\nKnown BIF magic:\n\n- `\"BIFF\"`\n\nKnown BIF versions:\n\n- `V1`\n- `E1`\n\nConceptually:\n\n```text\n+----------------------+\n| BIF header |\n+----------------------+\n| variable table |\n+----------------------+\n| payload 0 |\n+----------------------+\n| payload 1 |\n+----------------------+\n| ... |\n+----------------------+\n```\n\nEach variable-resource row records:\n\n- packed resource id\n- byte offset\n- stored size\n- resource type\n- optional `E1` compression metadata\n\n## Invariants\n\n- resource references remain typed rather than stringly indexed\n- the mapping from KEY entries to BIF-backed payload locations remains explicit\n- the same typed value may be inspected structurally and used as a\n `ResContainer`\n- KEY indexing and BIF payload storage are separate concepts\n- `BifResolver` exists because the KEY file references BIFs by filename and the\n actual stream-opening policy belongs to the caller\n\n## See also\n\n- [`nwnrs-resman`](https://docs.rs/nwnrs-resman), which consumes `KeyTable` as a\n resource container\n- [`nwnrs-install`](https://docs.rs/nwnrs-install), which uses KEY/BIF data to\n assemble a conventional install-backed resource stack\n\n## Why This Crate Exists\n\nIf you only think in terms of \"resource name to bytes,\" the KEY/BIF design\nlooks more complicated than it needs to be. If you think in terms of indexed\narchival storage, it becomes clear:\n\n- KEY is the index\n- BIF is the payload store\n- `ResId` is the join key\n\nThe crate makes that split explicit rather than hiding it behind opaque lookup\nmachinery.\n"include_str!("../README.md")]
34mod io;
5mod types;
67pub use io::*;
8pub use types::*;
910/// Common imports for consumers of this crate.
11pub mod prelude {
12pub use crate::{
13BifResolver, KeyBifContents, KeyBifEntry, KeyBifVersion, KeyError, KeyResult, KeyTable,
14ResId, VariableResource, read_key_table, read_key_table_from_file, write_key_and_bif,
15write_key_table_archive,
16 };
17}