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 UdfError {
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 { expected: u16, found: u16 },
20    /// Descriptor CRC mismatch
21    CrcMismatch { expected: u16, computed: u16 },
22    /// Unsupported UDF revision
23    UnsupportedRevision(u16),
24    /// Invalid partition reference
25    InvalidPartition(u16),
26    /// Invalid ICB (Information Control Block)
27    InvalidIcb,
28    /// File not found
29    NotFound,
30    /// Not a directory
31    NotADirectory,
32    /// Not a file
33    NotAFile,
34    /// Path too long
35    PathTooLong,
36    /// Invalid filename encoding
37    InvalidEncoding,
38    /// byte casting failed - the data buffer size doesn't match the target struct size.
39    PodCastError(bytemuck::PodCastError),
40}
41
42impl From<io::Error> for UdfError {
43    fn from(err: io::Error) -> Self {
44        Self::Io(err)
45    }
46}
47
48impl core::fmt::Display for UdfError {
49    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
50        match self {
51            Self::Io(e) => write!(f, "I/O error: {}", e),
52            Self::InvalidVrs => write!(f, "invalid or missing Volume Recognition Sequence"),
53            Self::InvalidVds(reason) => {
54                write!(f, "invalid or missing Volume Descriptor Sequence. {reason}")
55            }
56            Self::InvalidFsd => write!(f, "invalid or missing File Set Descriptor."),
57            Self::NoAnchor => write!(f, "no Anchor Volume Descriptor Pointer found"),
58            Self::InvalidTag { expected, found } => {
59                write!(
60                    f,
61                    "invalid descriptor tag: expected {}, found {}",
62                    expected, found
63                )
64            }
65            Self::CrcMismatch { expected, computed } => {
66                write!(
67                    f,
68                    "CRC mismatch: expected {:04x}, computed {:04x}",
69                    expected, computed
70                )
71            }
72            Self::UnsupportedRevision(rev) => {
73                write!(f, "unsupported UDF revision: {:04x}", rev)
74            }
75            Self::InvalidPartition(num) => write!(f, "invalid partition reference: {}", num),
76            Self::InvalidIcb => write!(f, "invalid Information Control Block"),
77            Self::NotFound => write!(f, "file or directory not found"),
78            Self::NotADirectory => write!(f, "not a directory"),
79            Self::NotAFile => write!(f, "not a file"),
80            Self::PathTooLong => write!(f, "path too long"),
81            Self::InvalidEncoding => write!(f, "invalid filename encoding"),
82            Self::PodCastError(err) => write!(
83                f,
84                "byte casting failed - the data buffer size doesn't match the target struct size. {err}"
85            ),
86        }
87    }
88}
89
90#[cfg(feature = "std")]
91impl std::error::Error for UdfError {
92    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
93        match self {
94            Self::Io(e) => Some(e),
95            _ => None,
96        }
97    }
98}
99
100/// Result type for UDF operations
101pub type UdfResult<T> = Result<T, UdfError>;