forensic_vfs/archive.rs
1//! The archive-layer result contract — [`ArchiveContents`] and [`Member`].
2//!
3//! The [`crate::registry::ArchiveOpen`] trait peels an archive/compression
4//! wrapper to one of these. A bare gzip/bzip2 stream yields a single decoded
5//! [`ArchiveContents::Stream`] (1→1); a multi-member archive (tar/zip/7z) yields
6//! its [`ArchiveContents::Members`] table (1→N). Either re-enters the resolver
7//! exactly like a container decode. See ADR 0008 (archives resolve as a
8//! first-class layer). This leaf carries only the contract types — every decoder
9//! and its compression dependencies live in the `archive-core` adapter.
10
11use crate::source::DynSource;
12
13/// What an [`crate::registry::ArchiveOpen::open`] peel produces.
14#[non_exhaustive]
15pub enum ArchiveContents {
16 /// A bare compression wrapper (gzip/bzip2): the single decoded stream. It
17 /// re-enters resolution just like a decoded container — `E01.gz → E01 → …`.
18 Stream(DynSource),
19 /// A multi-member archive (tar/zip/7z): the member table. A member that is
20 /// itself evidence (an `E01` inside a `.zip`) re-enters resolution on its own
21 /// [`Member::source`].
22 Members(Vec<Member>),
23}
24
25/// One member of a multi-member archive: its raw name and byte source. Archive
26/// member names are bytes, not guaranteed UTF-8, so `name` is `Vec<u8>`.
27pub struct Member {
28 /// The member's raw (possibly non-UTF-8) name.
29 pub name: Vec<u8>,
30 /// The member's byte source, ready to re-enter resolution.
31 pub source: DynSource,
32}