Skip to main content

hadris_apfs/
error.rs

1use core::fmt;
2
3/// APFS operation error.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum ApfsError {
6    /// Input ended before the requested structure could be parsed.
7    InputTooSmall,
8    /// The APFS magic value was not present.
9    InvalidMagic {
10        /// Expected magic bytes.
11        expected: [u8; 4],
12        /// Actual magic bytes found in input.
13        actual: [u8; 4],
14    },
15    /// A field contained an invalid value.
16    InvalidValue(&'static str),
17    /// Fletcher checksum verification failed.
18    ChecksumMismatch {
19        /// Checksum stored in the object header.
20        expected: u64,
21        /// Checksum computed from the object bytes.
22        actual: u64,
23    },
24    /// Arithmetic overflow while calculating an address or length.
25    AddressOverflow,
26    /// The image uses an APFS feature this reader does not implement.
27    Unsupported(&'static str),
28    /// Underlying I/O failed.
29    Io(hadris_io::ErrorKind),
30}
31
32/// Result type used by APFS operations.
33pub type Result<T> = core::result::Result<T, ApfsError>;
34
35impl ApfsError {
36    /// Converts a portable I/O error into an APFS error without retaining the backend type.
37    pub fn from_io<E: hadris_io::IoError>(error: hadris_io::Error<E>) -> Self {
38        Self::Io(error.kind())
39    }
40}
41
42impl fmt::Display for ApfsError {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        match self {
45            Self::InputTooSmall => f.write_str("APFS input too small"),
46            Self::InvalidMagic { expected, actual } => {
47                write!(f, "invalid APFS magic {actual:?}, expected {expected:?}",)
48            }
49            Self::InvalidValue(name) => write!(f, "invalid APFS value: {name}"),
50            Self::ChecksumMismatch { expected, actual } => write!(
51                f,
52                "APFS checksum mismatch: expected {expected:#x}, got {actual:#x}"
53            ),
54            Self::AddressOverflow => f.write_str("APFS address calculation overflowed"),
55            Self::Unsupported(feature) => write!(f, "unsupported APFS feature: {feature}"),
56            Self::Io(kind) => write!(f, "APFS I/O error: {kind:?}"),
57        }
58    }
59}
60
61#[cfg(feature = "std")]
62impl std::error::Error for ApfsError {}