1use std::borrow::Borrow;
2use std::error::Error as StdError;
3use std::fmt::{self, Display, Formatter};
4
5#[cfg(feature = "serde_json")]
6use serde_json::error::Error as JsonError;
7#[cfg(feature = "serde_yaml")]
8use serde_yaml::Error as YamlError;
9
10#[derive(Debug, Clone, Copy, PartialEq)]
11pub enum ErrorKind {
12 #[cfg(feature = "serde_json")]
13 Json,
14 #[cfg(feature = "serde_yaml")]
15 Yaml,
16 #[doc(hidden)]
17 __Unknown,
18}
19
20#[derive(Debug)]
21pub struct Error {
22 description: String,
23 kind: ErrorKind,
24 cause: Option<Box<StdError>>,
25}
26
27impl Error {
28 #[cfg(feature = "serde_json")]
29 pub fn json(err: JsonError) -> Self {
30 Error {
31 description: err.description().to_string(),
32 kind: ErrorKind::Json,
33 cause: Some(Box::new(err)),
34 }
35 }
36
37 #[cfg(feature = "serde_yaml")]
38 pub fn yaml(err: YamlError) -> Self {
39 Error {
40 description: err.description().to_string(),
41 kind: ErrorKind::Yaml,
42 cause: Some(Box::new(err)),
43 }
44 }
45
46 pub fn kind(&self) -> ErrorKind {
47 self.kind
48 }
49}
50
51impl StdError for Error {
52 fn description(&self) -> &str {
53 self.description.as_str()
54 }
55
56 fn cause(&self) -> Option<&StdError> {
57 match self.cause {
58 Some(ref err) => Some(err.borrow()),
59 None => None,
60 }
61 }
62}
63
64impl Display for Error {
65 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
66 self.description.fmt(f)
67 }
68}
69
70#[cfg(feature = "serde_json")]
71impl From<JsonError> for Error {
72 fn from(err: JsonError) -> Self {
73 Self::json(err)
74 }
75}
76
77#[cfg(feature = "serde_yaml")]
78impl From<YamlError> for Error {
79 fn from(err: YamlError) -> Self {
80 Self::yaml(err)
81 }
82}