Skip to main content

fstool/
error.rs

1//! Error type and `Result` alias for the crate.
2//!
3//! All public APIs return `fstool::Result<T>` = `Result<T, fstool::Error>`. The
4//! variants are intentionally small at this stage; further variants will be
5//! added as later layers (partition tables, filesystems, spec parsing) come
6//! online.
7
8use std::io;
9
10use thiserror::Error;
11
12/// Crate-wide error type.
13#[derive(Debug, Error)]
14pub enum Error {
15    /// Underlying I/O failure (file backend, host file source, etc.).
16    #[error("io: {0}")]
17    Io(#[from] io::Error),
18
19    /// A block-device operation referenced a byte range that lies (partly or
20    /// wholly) outside the device's logical extent. Includes slice violations.
21    #[error("out of bounds: offset {offset} len {len} exceeds device size {size}")]
22    OutOfBounds { offset: u64, len: u64, size: u64 },
23
24    /// On-disk structure failed validation (bad magic, bad checksum, etc.).
25    #[error("invalid image: {0}")]
26    InvalidImage(String),
27
28    /// The requested feature exists in the format but is not implemented in
29    /// this build of fstool. Used for clean "FAT32 not in v1" type messages.
30    #[error("unsupported feature: {0}")]
31    Unsupported(String),
32
33    /// A user-supplied value was malformed or contradictory (bad spec, etc.).
34    #[error("invalid argument: {0}")]
35    InvalidArgument(String),
36
37    /// The operation tried to modify a **streaming** filesystem — one
38    /// whose writer can't seek backward once bytes have been emitted.
39    /// Tar today; any future stream-of-records format that lands in
40    /// fstool. Distinct from [`Error::Immutable`] so callers can tell
41    /// "the writer fundamentally can't go back" apart from "the
42    /// on-disk layout was never designed for in-place edits."
43    #[error("{op}: {kind} is a streaming format — use `fstool repack` to produce a new one")]
44    Streaming {
45        /// The filesystem kind that refused (today: `"tar"`).
46        kind: &'static str,
47        /// Short verb describing the attempted op (`"add"`, `"rm"`, …).
48        /// Free-form; not a stable enum.
49        op: &'static str,
50    },
51
52    /// The operation tried to modify a **write-once** filesystem whose
53    /// on-disk layout has no in-place mutation hooks (no free-block
54    /// tracking, no journal). ISO 9660 and SquashFS today. The
55    /// writer can seek, but re-opening the image as writable isn't
56    /// part of the format's design — modifications go through
57    /// `fstool repack` to rebuild the image from scratch.
58    #[error("{op}: {kind} is a write-once format — use `fstool repack` to rebuild it")]
59    Immutable {
60        /// The filesystem kind that refused (today: `"iso9660"`,
61        /// `"squashfs"`).
62        kind: &'static str,
63        /// Short verb describing the attempted op.
64        op: &'static str,
65    },
66}
67
68/// Convenience alias used throughout the crate.
69pub type Result<T> = std::result::Result<T, Error>;