• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

royaltm / rust-delharc / 29785215315

20 Jul 2026 10:49PM UTC coverage: 93.666% (-0.6%) from 94.242%
29785215315

push

github

royaltm
fix header: check for known dir separators instead of system dependent ones

5 of 6 new or added lines in 1 file covered. (83.33%)

193 existing lines in 13 files now uncovered.

3978 of 4247 relevant lines covered (93.67%)

43937550.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

46.48
/src/error.rs
1
use core::{fmt, error};
2
#[cfg(feature = "std")]
3
use std::{io, collections::TryReserveError};
4
#[cfg(not(feature = "std"))]
5
use alloc::collections::TryReserveError;
6
use crate::stub_io::Read;
7

8
/// The result returned from functions in this crate.
9
///
10
/// `R` is the type of the data reader object.
11
pub type LhaResult<T, R> = Result<T, LhaError<<R as Read>::Error>>;
12

13
/// `delharc` error enum.
14
///
15
/// With `std` feature enabled `E` is [`std::io::Error`] and
16
/// [`LhaError`] can be converted to [`std::io::Error`] using
17
/// [`From`] or [`Into`].
18
#[derive(Debug, PartialEq, Eq)]
19
#[non_exhaustive]
20
pub enum LhaError<E> {
21
    /// An error occured while reading from the data stream
22
    Io(E),
23
    /// An error occured when parsing LHA header
24
    HeaderParse(LhaHeaderError),
25
    /// An error occured when decompressing a file
26
    Decompress(DecompressionError),
27
    /// A checksum mismatch error occured
28
    Checksum,
29
}
30

31
/// An enum of [`LhaHeader`] errors
32
#[derive(Debug, PartialEq, Eq)]
33
#[non_exhaustive]
34
pub enum LhaHeaderError {
35
    /// The header level is unknown
36
    UnknownLevel,
37
    /// First 2 bytes of level 3 header are incorrect
38
    Level3Signature,
39
    /// The extended header is too small
40
    ExtendedHeaderSize,
41
    /// A wrapping sum (level 0 and 1) did not match calculated value
42
    WrappingSumMismatch,
43
    /// A common header CRC-16 did not match calculated value
44
    Crc16Mismatch,
45
    /// Header size validation failed (level 0 and 1)
46
    SizeMismatch,
47
    /// Header long size validation failed (level 2 and 3)
48
    LongSizeMismatch,
49
    /// Header skip size validation failed (level 1)
50
    SkipSizeMismatch,
51
    /// Another common CRC-16 header found
52
    CommonHeader,
53
    /// A header was expected but 0 was encountered or end of stream
54
    HeaderNotFound,
55
    /// Memory allocation for extra header data has failed
56
    OutOfMemory,
57
}
58

59
/// An enum of errors returned from the static Huffman Tree building method.
60
#[derive(Debug, PartialEq, Eq)]
61
#[non_exhaustive]
62
pub enum BuildError {
63
    /// The tree code length slice is longer than the maximum
64
    /// number of potential leaf values.
65
    CodeLengthOverflow,
66
    /// There are not enough leaf nodes to cover the last tree level
67
    LeavesUndeflow,
68
    /// There are too many leaf nodes provided in code lengths
69
    LeavesOverflow,
70
    /// Allocating memory for tree nodes has failed
71
    OutOfMemory,
72
}
73

74
/// An enum of errors returned from decompression algorithms.
75
#[derive(Debug, PartialEq, Eq)]
76
#[non_exhaustive]
77
pub enum DecompressionError {
78
    /// Attempted to decompress a file with unsupported compression method
79
    UnsupportedCompression,
80
    /// LHv2/PMarc-v2 - too many code lengths requested for a command tree
81
    CommandCodeTableOverflow,
82
    /// LHv2 - too many code lengths requested for a history offset tree
83
    OffsetCodeTableOverflow,
84
    /// LHv2/PMarc-v2 - a requested single command code is too large
85
    CommandOverflow,
86
    /// LHv2 - a requested single history offset code is too large
87
    OffsetOverflow,
88
    /// LHv2 - too large code length decoded from the bit stream
89
    CodeLengthOverflow,
90
    #[cfg(feature = "pm")]
91
    #[cfg_attr(docsrs, doc(cfg(feature = "pm")))]
92
    /// PMarc - too large history distance
93
    HistoryDistanceOverflow,
94
    /// Bit-stream - too many bits requested for a given integer type capacity
95
    BitSizeOverflow,
96
    /// An error occured while building a Huffman Tree
97
    Tree(BuildError),
98
}
99

100
impl fmt::Display for LhaHeaderError {
101
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31✔
102
        use LhaHeaderError::*;
103
        match self {
31✔
104
            UnknownLevel => "unknown header level",
×
UNCOV
105
            Level3Signature => "level 3 signature mismatch",
×
106
            ExtendedHeaderSize => "not enough bytes in the extended header",
×
107
            WrappingSumMismatch => "wrapping checksum mismatch",
×
UNCOV
108
            Crc16Mismatch => "CRC-16 checksum mismatch",
×
109
            SizeMismatch => "size validation failed",
×
110
            LongSizeMismatch => "long size validation failed",
30✔
UNCOV
111
            SkipSizeMismatch => "skip size validation failed",
×
UNCOV
112
            CommonHeader => "duplicate CRC-16 header found",
×
113
            HeaderNotFound => "header not found",
1✔
UNCOV
114
            OutOfMemory => "memory allocation failed",
×
115
        }
116
        .fmt(f)
31✔
117
    }
31✔
118
}
119

120
impl error::Error for LhaHeaderError {}
121

122
impl From<TryReserveError> for LhaHeaderError {
UNCOV
123
    fn from(_err: TryReserveError) -> LhaHeaderError {
×
124
        LhaHeaderError::OutOfMemory
×
UNCOV
125
    }
×
126
}
127

128
impl fmt::Display for BuildError {
129
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30✔
130
        use BuildError::*;
131
        match self {
30✔
132
            CodeLengthOverflow => "too many code lengths",
×
133
            LeavesUndeflow => "not enough leaf nodes in code lengths",
30✔
UNCOV
134
            LeavesOverflow => "too many leaf nodes in code lengths",
×
UNCOV
135
            OutOfMemory => "memory allocation failed",
×
136
        }
137
        .fmt(f)
30✔
138
    }
30✔
139
}
140

141
impl error::Error for BuildError {}
142

143
impl From<TryReserveError> for BuildError {
UNCOV
144
    fn from(_err: TryReserveError) -> BuildError {
×
UNCOV
145
        BuildError::OutOfMemory
×
UNCOV
146
    }
×
147
}
148

149
impl fmt::Display for DecompressionError {
150
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60✔
151
        use DecompressionError::*;
152
        match self {
60✔
153
            UnsupportedCompression => "unsupported compression method",
×
154
            CommandCodeTableOverflow => "commands code length table is too large",
30✔
155
            OffsetCodeTableOverflow => "offset code length table is too large",
×
156
            CommandOverflow => "command code is too large",
×
UNCOV
157
            OffsetOverflow => "offset code is too large",
×
158
            #[cfg(feature = "pm")]
UNCOV
159
            HistoryDistanceOverflow => "history distance is too large",
×
UNCOV
160
            CodeLengthOverflow => "code length is too large",
×
UNCOV
161
            BitSizeOverflow => "too many bits requested",
×
162
            Tree(err) => return write!(f, "while building a tree: {}", err),
30✔
163
        }
164
        .fmt(f)
30✔
165
    }
60✔
166
}
167

168
impl error::Error for DecompressionError {}
169

170
impl From<BuildError> for DecompressionError {
171
    fn from(err: BuildError) -> DecompressionError {
11,835,147✔
172
        DecompressionError::Tree(err)
11,835,147✔
173
    }
11,835,147✔
174
}
175

176
impl<E: fmt::Display> fmt::Display for LhaError<E> {
177
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91✔
178
        use LhaError::*;
179
        match self {
91✔
UNCOV
180
            Io(e) => e.fmt(f),
×
181
            HeaderParse(e) => write!(f, "while parsing LHA header: {}", e),
31✔
182
            Decompress(e) => write!(f, "while decompressing: {}", e),
60✔
183
            Checksum => write!(f, "CRC-16 file checksum mismatch"),
×
184
        }
185
    }
91✔
186
}
187

188
impl<E: error::Error + 'static> error::Error for LhaError<E> {
189
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
×
190
        use LhaError::*;
UNCOV
191
        match self {
×
UNCOV
192
            Io(e) => Some(e),
×
193
            _ => None
×
194
        }
195
    }
×
196
}
197

198
impl<E> From<LhaHeaderError> for LhaError<E> {
199
    fn from(err: LhaHeaderError) -> LhaError<E> {
×
200
        LhaError::HeaderParse(err)
×
201
    }
×
202
}
203

204
impl<E> From<DecompressionError> for LhaError<E> {
UNCOV
205
    fn from(err: DecompressionError) -> LhaError<E> {
×
UNCOV
206
        LhaError::Decompress(err)
×
UNCOV
207
    }
×
208
}
209

210
impl<E> From<BuildError> for LhaError<E> {
211
    fn from(err: BuildError) -> LhaError<E> {
11,835,118✔
212
        LhaError::Decompress(err.into())
11,835,118✔
213
    }
11,835,118✔
214
}
215

216
#[cfg(feature = "std")]
217
impl From<LhaError<io::Error>> for io::Error {
218
    fn from(err: LhaError<io::Error>) -> Self {
1,353✔
219
        use LhaError::*;
220
        use io::{Error, ErrorKind};
221
        match err {
1,353✔
222
            Io(e) => e,
33✔
223
            err => Error::new(ErrorKind::InvalidData, err),
1,320✔
224
        }
225
    }
1,353✔
226
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc