zulip_api/
error.rs

1//! Library error types.
2
3use std::borrow::Cow;
4
5use serde::{Deserialize, Serialize};
6
7mod kind;
8
9pub use kind::ErrorKind;
10
11/// Represents error variants for the library.
12#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
13pub enum Error {
14    InvalidField {
15        field: String,
16        have: String,
17        expected: String,
18    },
19    Io {
20        kind: ErrorKind,
21        message: String,
22    },
23}
24
25impl Error {
26    /// Creates a new invalid field [Error].
27    pub fn invalid_field<'f, 'h, 'e, F, H, E>(field: F, have: H, expected: E) -> Self
28    where
29        F: Into<Cow<'f, str>>,
30        H: Into<Cow<'h, str>>,
31        E: Into<Cow<'e, str>>,
32    {
33        Self::InvalidField {
34            field: F::into(field).into(),
35            have: H::into(have).into(),
36            expected: E::into(expected).into(),
37        }
38    }
39
40    /// Creates a new I/O [Error] from a [`std::io::Error`].
41    pub fn std_io(err: std::io::Error) -> Self {
42        Self::Io {
43            kind: ErrorKind::from_io(err.kind()),
44            message: format!("{err}"),
45        }
46    }
47
48    /// Creates a new I/O [Error].
49    pub fn io<'m, M: Into<Cow<'m, str>>>(kind: ErrorKind, message: M) -> Self {
50        Self::Io {
51            kind,
52            message: M::into(message).into(),
53        }
54    }
55
56    /// Creates a new I/O other [Error].
57    pub fn io_other<'m, M: Into<Cow<'m, str>>>(message: M) -> Self {
58        Self::Io {
59            kind: ErrorKind::Other,
60            message: M::into(message).into(),
61        }
62    }
63
64    /// Creates a new I/O filename [Error].
65    pub fn io_filename<'m, M: Into<Cow<'m, str>>>(message: M) -> Self {
66        Self::Io {
67            kind: ErrorKind::InvalidFilename,
68            message: M::into(message).into(),
69        }
70    }
71}
72
73impl std::fmt::Display for Error {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        match self {
76            Self::InvalidField {
77                field,
78                have,
79                expected,
80            } => write!(f, "invalid {field}, have: {have}, expected: {expected}"),
81            Self::Io { kind, message } => write!(f, "I/O error, kind: {kind}, message: {message}"),
82        }
83    }
84}
85
86impl From<std::io::Error> for Error {
87    fn from(err: std::io::Error) -> Self {
88        Self::std_io(err)
89    }
90}
91
92impl From<Error> for std::io::Error {
93    fn from(err: Error) -> Self {
94        match err {
95            Error::Io { kind, message } => Self::new(kind.as_io(), message),
96            err => Self::other(err),
97        }
98    }
99}
100
101impl From<uuid::Error> for Error {
102    fn from(err: uuid::Error) -> Self {
103        Self::std_io(std::io::Error::other(err))
104    }
105}
106
107impl From<reqwest::Error> for Error {
108    fn from(err: reqwest::Error) -> Self {
109        Self::std_io(std::io::Error::other(err))
110    }
111}
112
113impl From<serde_json::Error> for Error {
114    fn from(err: serde_json::Error) -> Self {
115        Self::std_io(std::io::Error::other(err))
116    }
117}
118
119impl From<std::str::Utf8Error> for Error {
120    fn from(err: std::str::Utf8Error) -> Self {
121        Self::std_io(std::io::Error::other(err))
122    }
123}
124
125impl From<std::num::ParseIntError> for Error {
126    fn from(err: std::num::ParseIntError) -> Self {
127        Self::io(ErrorKind::Other, format!("{err}"))
128    }
129}
130
131impl From<reqwest::header::ToStrError> for Error {
132    fn from(err: reqwest::header::ToStrError) -> Self {
133        Self::io(ErrorKind::Other, format!("{err}"))
134    }
135}
136
137#[cfg(target_family = "wasm")]
138impl From<Error> for wasm_bindgen::JsValue {
139    fn from(err: Error) -> Self {
140        serde_wasm_bindgen::to_value(&err).unwrap_or_default()
141    }
142}
143
144impl serde::de::Error for Error {
145    fn custom<T: std::fmt::Display>(msg: T) -> Self {
146        Self::io(ErrorKind::Other, format!("{msg}"))
147    }
148}
149
150impl std::error::Error for Error {}