Skip to main content

intelhex/
error.rs

1/// All possible errors that may occur when processing Intel HEX format
2#[derive(Debug)]
3pub enum IntelHexError {
4    /// Errors that occur during parsing
5    Parse(ParseError),
6    /// Errors that occur during memory operations
7    Memory(MemoryError),
8    /// I/O errors
9    Io(std::io::Error),
10}
11
12/// Errors that can occur while parsing Intel HEX format
13#[derive(Debug)]
14pub enum ParseError {
15    /// Record does not begin with ':'
16    MissingStartCode,
17    /// Record is shorter than the minimum valid length
18    RecordTooShort,
19    /// Record exceeds maximum length (255 bytes payload)
20    RecordTooLong,
21    /// Record length is not even
22    RecordNotEvenLength,
23    /// Record contains non-hexadecimal characters
24    InvalidCharacters,
25    /// Checksum verification failed
26    ChecksumMismatch(u8, u8),
27    /// Actual payload length does not match the declared length
28    PayloadLengthMismatch,
29    /// Record type is not supported
30    UnsupportedRecordType(u8),
31    /// Payload length is invalid for the record type
32    InvalidLengthForType,
33    /// Load offset is invalid
34    InvalidLoadOffset,
35    /// Multiple start segment/linear address records found
36    MultipleStartAddressRecord,
37}
38
39/// Errors that can occur during memory operations
40#[derive(Debug)]
41pub enum MemoryError {
42    /// Address already contains data (overlapping addresses found)
43    AddressOverlap,
44}
45
46// Implement standard error trait
47impl std::error::Error for IntelHexError {
48    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
49        match self {
50            IntelHexError::Parse(err) => Some(err),
51            IntelHexError::Memory(err) => Some(err),
52            IntelHexError::Io(err) => Some(err),
53        }
54    }
55}
56
57impl std::error::Error for ParseError {}
58impl std::error::Error for MemoryError {}
59
60// Implement display trait
61impl std::fmt::Display for IntelHexError {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        match self {
64            IntelHexError::Parse(err) => write!(f, "Parse error: {}", err),
65            IntelHexError::Memory(err) => write!(f, "Memory error: {}", err),
66            IntelHexError::Io(err) => write!(f, "IO error: {}", err),
67        }
68    }
69}
70
71impl std::fmt::Display for ParseError {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        match self {
74            ParseError::MissingStartCode => write!(f, "missing start code ':'"),
75            ParseError::RecordTooShort => write!(f, "record too short"),
76            ParseError::RecordTooLong => write!(f, "record too long"),
77            ParseError::RecordNotEvenLength => {
78                write!(f, "record does not contain a whole number of bytes")
79            }
80            ParseError::InvalidCharacters => write!(f, "invalid characters encountered in record"),
81            ParseError::ChecksumMismatch(found, expected) => {
82                write!(
83                    f,
84                    "checksum mismatch, found {}, expected {}",
85                    found, expected
86                )
87            }
88            ParseError::PayloadLengthMismatch => {
89                write!(f, "payload length does not match record header")
90            }
91            ParseError::UnsupportedRecordType(record_type) => {
92                write!(f, "unsupported record type '{:02X}'", record_type)
93            }
94            ParseError::InvalidLengthForType => write!(f, "payload length invalid for record type"),
95            ParseError::InvalidLoadOffset => write!(f, "invalid load offset"),
96            ParseError::MultipleStartAddressRecord => {
97                write!(f, "multiple start segment/linear address records")
98            }
99        }
100    }
101}
102
103impl std::fmt::Display for MemoryError {
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        match self {
106            MemoryError::AddressOverlap => write!(
107                f,
108                "address already contains data (overlapping addresses found)"
109            ),
110        }
111    }
112}
113
114// Implement error conversions
115impl From<std::io::Error> for IntelHexError {
116    fn from(err: std::io::Error) -> Self {
117        IntelHexError::Io(err)
118    }
119}
120
121impl From<ParseError> for IntelHexError {
122    fn from(err: ParseError) -> Self {
123        IntelHexError::Parse(err)
124    }
125}
126
127impl From<MemoryError> for IntelHexError {
128    fn from(err: MemoryError) -> Self {
129        IntelHexError::Memory(err)
130    }
131}