zip/
result.rs

1#![allow(unknown_lints)] // non_local_definitions isn't in Rust 1.70
2#![allow(non_local_definitions)]
3//! Error types that can be emitted from this library
4
5use displaydoc::Display;
6use thiserror::Error;
7
8use std::error::Error;
9use std::fmt;
10use std::io;
11use std::num::TryFromIntError;
12use std::string::FromUtf8Error;
13
14/// Generic result type with ZipError as its error variant
15pub type ZipResult<T> = Result<T, ZipError>;
16
17/// Error type for Zip
18#[derive(Debug, Display, Error)]
19#[non_exhaustive]
20pub enum ZipError {
21    /// i/o error: {0}
22    Io(#[from] io::Error),
23
24    /// invalid Zip archive: {0}
25    InvalidArchive(&'static str),
26
27    /// unsupported Zip archive: {0}
28    UnsupportedArchive(&'static str),
29
30    /// specified file not found in archive
31    FileNotFound,
32
33    /// The password provided is incorrect
34    InvalidPassword,
35}
36
37impl ZipError {
38    /// The text used as an error when a password is required and not supplied
39    ///
40    /// ```rust,no_run
41    /// # use zip::result::ZipError;
42    /// # let mut archive = zip::ZipArchive::new(std::io::Cursor::new(&[])).unwrap();
43    /// match archive.by_index(1) {
44    ///     Err(ZipError::UnsupportedArchive(ZipError::PASSWORD_REQUIRED)) => eprintln!("a password is needed to unzip this file"),
45    ///     _ => (),
46    /// }
47    /// # ()
48    /// ```
49    pub const PASSWORD_REQUIRED: &'static str = "Password required to decrypt file";
50}
51
52impl From<ZipError> for io::Error {
53    fn from(err: ZipError) -> io::Error {
54        let kind = match &err {
55            ZipError::Io(err) => err.kind(),
56            ZipError::InvalidArchive(_) => io::ErrorKind::InvalidData,
57            ZipError::UnsupportedArchive(_) => io::ErrorKind::Unsupported,
58            ZipError::FileNotFound => io::ErrorKind::NotFound,
59            ZipError::InvalidPassword => io::ErrorKind::InvalidInput,
60        };
61
62        io::Error::new(kind, err)
63    }
64}
65
66impl From<DateTimeRangeError> for ZipError {
67    fn from(_: DateTimeRangeError) -> Self {
68        ZipError::InvalidArchive("Invalid date or time")
69    }
70}
71
72impl From<FromUtf8Error> for ZipError {
73    fn from(_: FromUtf8Error) -> Self {
74        ZipError::InvalidArchive("Invalid UTF-8")
75    }
76}
77
78/// Error type for time parsing
79#[derive(Debug)]
80pub struct DateTimeRangeError;
81
82// TryFromIntError is also an out-of-range error.
83impl From<TryFromIntError> for DateTimeRangeError {
84    fn from(_value: TryFromIntError) -> Self {
85        DateTimeRangeError
86    }
87}
88
89impl fmt::Display for DateTimeRangeError {
90    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
91        write!(
92            fmt,
93            "a date could not be represented within the bounds the MS-DOS date range (1980-2107)"
94        )
95    }
96}
97
98impl Error for DateTimeRangeError {}