better_limit_reader/
error.rs

1use crate::{error_from, LimitReaderOutputBuilderError};
2use std::{
3    error::Error as StdError,
4    fmt::{self},
5    num::TryFromIntError,
6    string::FromUtf8Error,
7};
8
9/// Boxed error, a ptr to the Error via dynamic dispatch allocated on the heap at run time.
10#[allow(clippy::module_name_repetitions)]
11pub type BoxError = Box<dyn StdError + Send + Sync>;
12
13/// Error type
14pub struct Error {
15    kind: ErrorKind,
16    error: BoxError,
17}
18
19#[derive(Debug)]
20#[non_exhaustive]
21#[allow(clippy::module_name_repetitions)]
22#[allow(clippy::enum_variant_names)]
23pub enum ErrorKind {
24    ReadError,
25    IoError,
26    LimitReaderOutputBuilderError,
27    Utf8Error,
28    TryFromIntError,
29}
30
31impl ErrorKind {
32    pub(crate) fn as_str(&self) -> &'static str {
33        #[allow(clippy::enum_glob_use)]
34        use ErrorKind::*;
35        // tidy-alphabetical-start
36        match *self {
37            ReadError => "read error",
38            IoError => "io error",
39            Utf8Error => "invalid utf-8",
40            LimitReaderOutputBuilderError => "builder error",
41            TryFromIntError => "conversion error",
42        }
43    }
44}
45
46impl fmt::Display for ErrorKind {
47    /// Shows a human-readable description of the `ErrorKind`.
48    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
49        fmt.write_str(self.as_str())
50    }
51}
52
53impl StdError for Error {
54    fn source(&self) -> Option<&(dyn StdError + 'static)> {
55        Some(&*self.error)
56    }
57}
58
59#[allow(dead_code)]
60impl Error {
61    pub fn new<E>(kind: ErrorKind, error: E) -> Error
62    where
63        E: Into<BoxError>,
64    {
65        Self::_new(kind, error.into())
66    }
67
68    fn _new(kind: ErrorKind, error: BoxError) -> Error {
69        Error { kind, error }
70    }
71}
72
73impl fmt::Debug for Error {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        let mut f = f.debug_tuple("better-limit-reader::Error");
76        f.field(&self.kind);
77        f.field(&self.error);
78        f.finish()
79    }
80}
81
82impl fmt::Display for Error {
83    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84        write!(f, "Error: {}", &self.error)
85    }
86}
87
88error_from!(std::io::Error, ErrorKind::IoError);
89error_from!(FromUtf8Error, ErrorKind::Utf8Error);
90error_from!(
91    LimitReaderOutputBuilderError,
92    ErrorKind::LimitReaderOutputBuilderError
93);
94error_from!(TryFromIntError, ErrorKind::TryFromIntError);
95
96#[macro_use]
97pub mod macros {
98    /// Implement provided Error type with a suitable `ErrorKind`
99    #[macro_export]
100    macro_rules! error_from {
101        ($typ:ty, $kind:expr) => {
102            impl From<$typ> for Error {
103                fn from(error: $typ) -> Self {
104                    Self {
105                        error: error.into(),
106                        kind: $kind,
107                    }
108                }
109            }
110        };
111    }
112}
113
114/// Default error for [`crate::prelude::LimitReader`]
115#[allow(clippy::module_name_repetitions)]
116pub type LimitReaderError = Error;