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

royaltm / rust-delharc / 29527820793

16 Jul 2026 07:23PM UTC coverage: 94.093% (-0.3%) from 94.399%
29527820793

push

github

royaltm
lhv2: sanity assert

1 of 1 new or added line in 1 file covered. (100.0%)

45 existing lines in 3 files now uncovered.

3122 of 3318 relevant lines covered (94.09%)

25133530.79 hits per line

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

38.03
/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
pub type LhaResult<T, R> = Result<T, LhaError<<R as Read>::Error>>;
9

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

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

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

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

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

115
impl error::Error for LhaHeaderError {}
116

117
impl From<TryReserveError> for LhaHeaderError {
118
    fn from(_err: TryReserveError) -> LhaHeaderError {
×
119
        LhaHeaderError::OutOfMemory
×
120
    }
×
121
}
122

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

136
impl error::Error for BuildError {}
137

138
impl From<TryReserveError> for BuildError {
139
    fn from(_err: TryReserveError) -> BuildError {
×
UNCOV
140
        BuildError::OutOfMemory
×
UNCOV
141
    }
×
142
}
143

144
impl fmt::Display for DecompressionError {
145
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24✔
146
        use DecompressionError::*;
147
        match self {
24✔
UNCOV
148
            UnsupportedCompression => "unsupported compression method",
×
149
            TemporaryCodeTableOverflow => "temporary code length table size overflow",
24✔
UNCOV
150
            CommandCodeTableOverflow => "commands code length table size overflow",
×
UNCOV
151
            OffsetCodeTableOverflow => "offset code length table size overflow",
×
UNCOV
152
            CommandOverflow => "command code overflow",
×
UNCOV
153
            OffsetOverflow => "offset code overflow",
×
UNCOV
154
            CodeLengthOverflow => "code length overflow",
×
155
            BitSizeOverflow => "too many bits requested",
×
UNCOV
156
            Tree(err) => return write!(f, "while building a tree: {}", err)
×
157
        }
158
        .fmt(f)
24✔
159
    }
24✔
160
}
161

162
impl error::Error for DecompressionError {}
163

164
impl From<BuildError> for DecompressionError {
165
    fn from(err: BuildError) -> DecompressionError {
725,571✔
166
        DecompressionError::Tree(err)
725,571✔
167
    }
725,571✔
168
}
169

170
impl<E: fmt::Display> fmt::Display for LhaError<E> {
171
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49✔
172
        use LhaError::*;
173
        match self {
49✔
UNCOV
174
            Io(e) => e.fmt(f),
×
175
            HeaderParse(e) => write!(f, "while parsing LHA header: {}", e),
25✔
176
            Decompress(e) => write!(f, "while decompressing: {}", e),
24✔
UNCOV
177
            Checksum => write!(f, "CRC-16 file checksum mismatch"),
×
178
        }
179
    }
49✔
180
}
181

182
impl<E: error::Error + 'static> error::Error for LhaError<E> {
UNCOV
183
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
×
184
        use LhaError::*;
UNCOV
185
        match self {
×
UNCOV
186
            Io(e) => Some(e),
×
UNCOV
187
            _ => None
×
188
        }
UNCOV
189
    }
×
190
}
191

192
impl<E> From<LhaHeaderError> for LhaError<E> {
UNCOV
193
    fn from(err: LhaHeaderError) -> LhaError<E> {
×
UNCOV
194
        LhaError::HeaderParse(err)
×
UNCOV
195
    }
×
196
}
197

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

204
impl<E> From<BuildError> for LhaError<E> {
205
    fn from(err: BuildError) -> LhaError<E> {
725,571✔
206
        LhaError::Decompress(err.into())
725,571✔
207
    }
725,571✔
208
}
209

210
#[cfg(feature = "std")]
211
impl From<LhaError<io::Error>> for io::Error {
212
    fn from(err: LhaError<io::Error>) -> Self {
867✔
213
        use LhaError::*;
214
        use io::{Error, ErrorKind};
215
        match err {
867✔
216
            Io(e) => e,
27✔
217
            err => Error::new(ErrorKind::InvalidData, err),
840✔
218
        }
219
    }
867✔
220
}
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