1#![forbid(unsafe_code)]
2#![doc = "# nwnrs-erf\n\n`nwnrs-erf` reads and writes the ERF-family archive formats used by\nNeverwinter Nights, including `ERF`, `MOD`, `HAK`, and `NWM`.\n\n## Scope\n\n- parse typed ERF archives and their resource tables\n- expose archive contents as an [`Erf`] value\n- implement `nwnrs-resman` container behavior for archive-backed resolution\n- write typed archive data back to disk\n\nThe principal entry points are [`read_erf`], [`read_erf_from_file`],\n[`read_erf_shared`], and [`write_erf`].\n\n## Public Surface\n\n- `Erf`\n- `ErfVersion`\n- `ErfWriteOptions`\n- `ErfError`\n- `ErfResult`\n- `read_erf`\n- `read_erf_from_file`\n- `read_erf_shared`\n- `write_erf`\n- `write_erf_archive`\n- `write_erf_with_options`\n\n## Core Model\n\n`Erf` preserves:\n\n- outer archive type and version\n- archive filename\n- build year and day\n- top-level `str_ref`\n- localized strings\n- ordered entries\n- optional enhanced-edition `oid`\n- preserved padding between key and resource lists\n\nThe same typed value also implements `ResContainer`.\n\n## Binary Layout\n\nHeader size: `160` bytes.\n\nKnown outer file types:\n\n- `ERF `\n- `MOD `\n- `HAK `\n- `NWM `\n\nKnown versions:\n\n- `V1`\n- `E1`\n\nHeader shape:\n\n```text\nfile_type [4]\nfile_version [4]\nloc_str_count i32\nloc_string_size i32\nentry_count i32\noffset_to_loc_str i32\noffset_to_key_list i32\noffset_to_resource_list i32\nbuild_year i32\nbuild_day i32\nstr_ref i32\nreserved or OID area remaining header bytes\n```\n\nArchive body:\n\n```text\n+----------------------+\n| 160-byte header |\n+----------------------+\n| localized strings |\n+----------------------+\n| key list |\n+----------------------+\n| resource list |\n+----------------------+\n| resource data area |\n+----------------------+\n```\n\nEntry-table sizes differ by version:\n\n- key entry\n - `V1`: 24 bytes\n - `E1`: 44 bytes\n- resource entry\n - `V1`: 8 bytes\n - `E1`: 16 bytes\n\n`E1` adds optional compression metadata and archive OID support.\n\n## Invariants\n\n- resource references and archive membership are represented explicitly\n- archive semantics are preserved independently of the container filename\n- the same typed archive value can be inspected structurally and used as a\n `ResContainer`\n- stored entry order and resource-list padding are preserved on write\n- `E1` per-entry compression metadata is physical-storage metadata, not content\n semantics\n\n## See also\n\n- [`nwnrs-resman`](https://docs.rs/nwnrs-resman), which layers multiple\n containers in precedence order\n- [`nwnrs-key`](https://docs.rs/nwnrs-key), which models the KEY/BIF storage\n family\n\n## Why This Crate Exists\n\n`ERF` is both:\n\n- a physical archive format\n- a logical resource container\n\nThis crate models both sides explicitly without conflating them with global\nlookup policy, which belongs in `nwnrs-resman`.\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::{
13Erf, ErfError, ErfResult, ErfVersion, ErfWriteOptions, read_erf, read_erf_from_file,
14read_erf_shared, write_erf, write_erf_archive, write_erf_with_options,
15 };
16}