zipatch-rs 1.0.0

Parser for FFXIV ZiPatch patch files
Documentation
/// All failures returned by parsing or applying a `ZiPatch` stream.
#[non_exhaustive]
#[derive(Debug, thiserror::Error)]
pub enum ZiPatchError {
    /// Underlying I/O failure from the patch source or target filesystem.
    #[error("I/O error: {0}")]
    Io(#[from] std::io::Error),

    /// The 12-byte `ZiPatch` magic header was missing or did not match.
    #[error("invalid magic bytes")]
    InvalidMagic,

    /// A 4-byte chunk tag was not recognised by the parser.
    #[error("unknown chunk tag: {0:?}")]
    UnknownChunkTag([u8; 4]),

    /// A SQPK sub-command byte was not recognised by the parser.
    #[error("unknown SQPK command: {0:#x}")]
    UnknownSqpkCommand(u8),

    /// A chunk's recorded CRC32 did not match the computed CRC32.
    #[error("CRC32 mismatch on chunk {tag:?}: expected {expected:#010x}, got {actual:#010x}")]
    ChecksumMismatch {
        /// Tag of the chunk whose checksum failed.
        tag: [u8; 4],
        /// CRC32 stored in the patch file.
        expected: u32,
        /// CRC32 computed over the actual chunk bytes.
        actual: u32,
    },

    /// DEFLATE decompression of a `SqpkFile` block failed.
    #[error("decompression error")]
    Decompress(#[source] std::io::Error),

    /// A field value failed a parser invariant (e.g. negative size).
    #[error("invalid field: {context}")]
    InvalidField {
        /// Human-readable description of which field was invalid.
        context: &'static str,
    },

    /// A chunk declared a size larger than the parser's maximum.
    #[error("chunk size {0} exceeds maximum")]
    OversizedChunk(usize),

    /// A `SqpkFile` operation byte was not recognised.
    #[error("unknown SqpkFile operation: {0:#02x}")]
    UnknownFileOperation(u8),

    /// A UTF-8 decode failed when reading a path or name field.
    #[error("UTF-8 decode error")]
    Utf8Error(#[from] std::string::FromUtf8Error),

    /// A `binrw` parser produced an error; wraps the underlying cause.
    #[error("binrw parse error: {0}")]
    BinrwError(#[from] binrw::Error),

    /// A `SqpkFile` carried a negative `file_offset` that cannot be applied.
    #[error("negative file_offset in SqpkFile: {0}")]
    NegativeFileOffset(i64),

    /// Stream ended without an `EOF_` chunk; download or copy was truncated.
    #[error("patch file ended without EOF_ chunk (truncated download?)")]
    TruncatedPatch,
}