1use std::fmt;
2
3pub type Result<T, E = Error> = std::result::Result<T, E>;
4
5#[derive(Debug)]
6pub enum Error {
7 Io(std::io::Error),
8 InvalidFormat(&'static str),
9 InvalidData(String),
10 Truncated {
11 context: &'static str,
12 needed: usize,
13 remaining: usize,
14 },
15 LimitExceeded {
16 limit: &'static str,
17 value: u64,
18 max: u64,
19 },
20 ChecksumMismatch {
21 context: &'static str,
22 expected: u32,
23 actual: u32,
24 },
25 Decode {
26 context: &'static str,
27 encoding: &'static str,
28 },
29 MissingPasscode,
30 Unsupported(&'static str),
31}
32
33impl Error {
34 pub fn truncated(context: &'static str, needed: usize, remaining: usize) -> Self {
35 Self::Truncated {
36 context,
37 needed,
38 remaining,
39 }
40 }
41}
42
43impl fmt::Display for Error {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 match self {
46 Self::Io(error) => write!(f, "I/O error: {error}"),
47 Self::InvalidFormat(context) => write!(f, "invalid format: {context}"),
48 Self::InvalidData(context) => write!(f, "invalid data: {context}"),
49 Self::Truncated {
50 context,
51 needed,
52 remaining,
53 } => write!(
54 f,
55 "truncated {context}: need {needed} bytes, have {remaining}"
56 ),
57 Self::LimitExceeded { limit, value, max } => {
58 write!(f, "limit exceeded for {limit}: {value} > {max}")
59 }
60 Self::ChecksumMismatch {
61 context,
62 expected,
63 actual,
64 } => write!(
65 f,
66 "checksum mismatch for {context}: expected {expected:#010x}, got {actual:#010x}"
67 ),
68 Self::Decode { context, encoding } => {
69 write!(f, "failed to decode {context} using {encoding}")
70 }
71 Self::MissingPasscode => write!(f, "dictionary requires a passcode"),
72 Self::Unsupported(feature) => write!(f, "unsupported feature: {feature}"),
73 }
74 }
75}
76
77impl std::error::Error for Error {
78 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
79 match self {
80 Self::Io(error) => Some(error),
81 _ => None,
82 }
83 }
84}
85
86impl From<std::io::Error> for Error {
87 fn from(value: std::io::Error) -> Self {
88 Self::Io(value)
89 }
90}