Skip to main content

hadris_udf/
error.rs

1//! UDF-specific error types
2
3use hadris_io as io;
4
5/// Errors that can occur when reading or writing UDF filesystems
6#[derive(Debug)]
7pub enum Error {
8    /// I/O error
9    Io(io::Error),
10    /// Invalid or missing Volume Recognition Sequence
11    InvalidVrs,
12    /// Invalid or missing Volume Descriptor Sequence
13    InvalidVds(&'static str),
14    /// Invalid or missing File Set Descriptor
15    InvalidFsd,
16    /// No Anchor Volume Descriptor Pointer found
17    NoAnchor,
18    /// Invalid descriptor tag
19    InvalidTag {
20        /// Descriptor tag identifier required at this location.
21        expected: u16,
22        /// Descriptor tag identifier found on the medium.
23        found: u16,
24    },
25    /// Descriptor CRC mismatch
26    CrcMismatch {
27        /// CRC stored in the descriptor tag.
28        expected: u16,
29        /// CRC computed from the descriptor payload.
30        computed: u16,
31    },
32    /// Invalid partition reference
33    InvalidPartition(u16),
34    /// Invalid ICB (Information Control Block)
35    InvalidIcb,
36    /// File not found
37    NotFound,
38    /// Not a directory
39    NotADirectory,
40    /// Not a file
41    NotAFile,
42    /// Path too long
43    PathTooLong,
44    /// Invalid filename encoding
45    InvalidEncoding,
46    /// Allocation descriptors do not fit in a File Entry sector
47    TooManyAllocationDescriptors,
48    /// Directory nesting exceeds the supported depth
49    DirectoryNestingTooDeep,
50    /// byte casting failed - the data buffer size doesn't match the target struct size.
51    PodCastError(bytemuck::PodCastError),
52}
53
54impl<E: io::IoError> From<io::Error<E>> for Error {
55    fn from(err: io::Error<E>) -> Self {
56        Self::Io(err.erase())
57    }
58}
59
60impl core::fmt::Display for Error {
61    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
62        match self {
63            Self::Io(e) => write!(f, "I/O error: {e}"),
64            Self::InvalidVrs => write!(f, "invalid or missing Volume Recognition Sequence"),
65            Self::InvalidVds(reason) => {
66                write!(f, "invalid or missing Volume Descriptor Sequence. {reason}")
67            }
68            Self::InvalidFsd => write!(f, "invalid or missing File Set Descriptor."),
69            Self::NoAnchor => write!(f, "no Anchor Volume Descriptor Pointer found"),
70            Self::InvalidTag { expected, found } => {
71                write!(
72                    f,
73                    "invalid descriptor tag: expected {expected}, found {found}"
74                )
75            }
76            Self::CrcMismatch { expected, computed } => {
77                write!(
78                    f,
79                    "CRC mismatch: expected {expected:04x}, computed {computed:04x}"
80                )
81            }
82            Self::InvalidPartition(num) => write!(f, "invalid partition reference: {num}"),
83            Self::InvalidIcb => write!(f, "invalid Information Control Block"),
84            Self::NotFound => write!(f, "file or directory not found"),
85            Self::NotADirectory => write!(f, "not a directory"),
86            Self::NotAFile => write!(f, "not a file"),
87            Self::PathTooLong => write!(f, "path too long"),
88            Self::InvalidEncoding => write!(f, "invalid filename encoding"),
89            Self::TooManyAllocationDescriptors => {
90                write!(f, "allocation descriptors exceed one File Entry sector")
91            }
92            Self::DirectoryNestingTooDeep => write!(f, "directory nesting too deep"),
93            Self::PodCastError(err) => write!(
94                f,
95                "byte casting failed - the data buffer size doesn't match the target struct size. {err}"
96            ),
97        }
98    }
99}
100
101#[cfg(feature = "std")]
102impl std::error::Error for Error {
103    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
104        match self {
105            Self::Io(e) => Some(e),
106            _ => None,
107        }
108    }
109}
110
111/// Result type for UDF operations
112pub type Result<T> = core::result::Result<T, Error>;