1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std::{
error::Error,
fmt, io,
num::{ParseIntError, TryFromIntError},
str,
};
#[derive(Debug)]
#[non_exhaustive]
pub enum VpkError {
InvalidHeader(String),
InvalidMethod(u8),
BadLookBack(usize, usize),
BadTreeEncoding,
BadUserTree(EncodeTreeParseErr),
InputTooBig(TryFromIntError),
Utf8Error(str::Utf8Error),
Io(io::Error),
}
impl fmt::Display for VpkError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
VpkError::InvalidHeader(s) => write!(f, "Invalid ascii string '{}' in header", s),
VpkError::InvalidMethod(n) => {
write!(f, "VPK method {} is invalid and not supported", n)
}
VpkError::BadLookBack(mb, size) => write!(
f,
"Bad input file: asked to move back {} bytes in buffer of only {} bytes",
mb, size
),
VpkError::BadTreeEncoding => write!(f, "Huffman tree value couldn't be read"),
VpkError::BadUserTree(_) => {
write!(f, "Issue parsing user-provided huffman code tree string")
}
VpkError::InputTooBig(_) => write!(f, "Input file size too big to fit in 32-bit word"),
VpkError::Utf8Error(_) => write!(f, "Couldn't read magic bytes"),
VpkError::Io(_) => write!(f, "IO issue"),
}
}
}
impl Error for VpkError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
VpkError::BadUserTree(e) => Some(e as &dyn Error),
VpkError::InputTooBig(e) => Some(e as &dyn Error),
VpkError::Utf8Error(e) => Some(e as &dyn Error),
VpkError::Io(e) => Some(e as &dyn Error),
_ => None,
}
}
}
impl From<EncodeTreeParseErr> for VpkError {
fn from(e: EncodeTreeParseErr) -> Self {
Self::BadUserTree(e)
}
}
impl From<io::Error> for VpkError {
fn from(e: io::Error) -> Self {
Self::Io(e)
}
}
impl From<TryFromIntError> for VpkError {
fn from(e: TryFromIntError) -> Self {
Self::InputTooBig(e)
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum EncodeTreeParseErr {
LexNum(ParseIntError, usize),
LexUnexp(char, usize),
ParseUnexp(&'static str, usize),
ParseUnexpEnd,
}
impl fmt::Display for EncodeTreeParseErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EncodeTreeParseErr::LexNum(_, p) => {
write!(f, "Issue parsing number in tree string at pos {}", p)
}
EncodeTreeParseErr::LexUnexp(c, p) => {
write!(f, "Unexpected character '{}' at pos {}", c, p)
}
EncodeTreeParseErr::ParseUnexp(s, p) => {
write!(f, "Unexpected token '{}' at pos {}", s, p)
}
EncodeTreeParseErr::ParseUnexpEnd => write!(f, "Unexpected end of tokens"),
}
}
}
impl Error for EncodeTreeParseErr {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
EncodeTreeParseErr::LexNum(e, _) => Some(e as &dyn Error),
_ => None,
}
}
}