Skip to main content

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}