1#[derive(Debug)]
3pub struct Error {
4 inner: Box<ErrorInner>,
5}
6
7impl Error {
8 pub fn eocd_offset(&self) -> Option<u64> {
12 self.inner.eocd_offset
13 }
14
15 pub(crate) fn with_eocd_offset(mut self, offset: u64) -> Self {
17 self.inner.eocd_offset = Some(offset);
18 self
19 }
20}
21
22impl Error {
23 pub(crate) fn io(err: std::io::Error) -> Error {
24 Error::from(ErrorKind::IO(err))
25 }
26
27 pub(crate) fn utf8(err: std::str::Utf8Error) -> Error {
28 Error::from(ErrorKind::InvalidUtf8(err))
29 }
30
31 pub(crate) fn is_eof(&self) -> bool {
32 matches!(self.inner.kind, ErrorKind::Eof)
33 }
34
35 pub fn kind(&self) -> &ErrorKind {
37 &self.inner.kind
38 }
39}
40
41#[derive(Debug)]
42struct ErrorInner {
43 kind: ErrorKind,
44 eocd_offset: Option<u64>,
45}
46
47#[derive(Debug)]
49#[non_exhaustive]
50pub enum ErrorKind {
51 MissingEndOfCentralDirectory,
53
54 MissingZip64EndOfCentralDirectory,
56
57 BufferTooSmall,
59
60 InvalidSignature { expected: u32, actual: u32 },
62
63 InvalidChecksum { expected: u32, actual: u32 },
65
66 InvalidSize { expected: u64, actual: u64 },
68
69 InvalidUtf8(std::str::Utf8Error),
71
72 InvalidInput { msg: String },
74
75 InvalidEndOfCentralDirectory,
77
78 IO(std::io::Error),
80
81 Eof,
83}
84
85impl std::error::Error for Error {}
86
87impl std::fmt::Display for Error {
88 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
89 write!(f, "{}", self.inner.kind)?;
90 Ok(())
91 }
92}
93
94impl std::fmt::Display for ErrorKind {
95 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
96 match *self {
97 ErrorKind::IO(ref err) => err.fmt(f),
98 ErrorKind::MissingEndOfCentralDirectory => {
99 write!(f, "Missing end of central directory")
100 }
101 ErrorKind::MissingZip64EndOfCentralDirectory => {
102 write!(f, "Missing zip64 end of central directory")
103 }
104 ErrorKind::BufferTooSmall => {
105 write!(f, "Buffer size too small")
106 }
107 ErrorKind::Eof => {
108 write!(f, "Unexpected end of file")
109 }
110 ErrorKind::InvalidSignature { expected, actual } => {
111 write!(
112 f,
113 "Invalid signature: expected 0x{:08x}, got 0x{:08x}",
114 expected, actual
115 )
116 }
117 ErrorKind::InvalidChecksum { expected, actual } => {
118 write!(
119 f,
120 "Invalid checksum: expected 0x{:08x}, got 0x{:08x}",
121 expected, actual
122 )
123 }
124 ErrorKind::InvalidSize { expected, actual } => {
125 write!(f, "Invalid size: expected {}, got {}", expected, actual)
126 }
127 ErrorKind::InvalidUtf8(ref err) => {
128 write!(f, "Invalid UTF-8: {}", err)
129 }
130 ErrorKind::InvalidInput { ref msg } => {
131 write!(f, "Invalid input: {}", msg)
132 }
133 ErrorKind::InvalidEndOfCentralDirectory => {
134 write!(f, "Invalid end of central directory")
135 }
136 }
137 }
138}
139
140impl From<ErrorKind> for Error {
141 fn from(kind: ErrorKind) -> Error {
142 Error {
143 inner: Box::new(ErrorInner {
144 kind,
145 eocd_offset: None,
146 }),
147 }
148 }
149}
150
151impl From<std::io::Error> for Error {
152 fn from(err: std::io::Error) -> Error {
153 Error::from(ErrorKind::IO(err))
154 }
155}