1use crate::{parsers::ParseError, Encoding};
4use std::error::Error as StdError;
5use std::fmt::Display;
6use std::io;
7use thiserror::Error;
8
9pub type Result<T, E = Error> = std::result::Result<T, E>;
11
12#[non_exhaustive]
14#[derive(Error, Debug)]
15pub enum Error {
16 #[error("{0}")]
18 Message(String),
19
20 #[error("operation is not supported for encoding `{0}`")]
22 UnsupportedEncoding(Encoding),
23
24 #[error(transparent)]
26 ParseError(#[from] ParseError),
27
28 #[error(transparent)]
30 Io(#[from] io::Error),
31
32 #[error("invalid glob pattern `{pattern}`")]
34 GlobPatternError {
35 pattern: String,
37 source: glob::PatternError,
39 },
40
41 #[error("unable to fetch remote data source")]
43 RequestError(#[from] ureq::Error),
44
45 #[error(transparent)]
47 Serde(Box<dyn StdError + Send + Sync>),
48}
49
50impl Error {
51 pub(crate) fn new<T>(msg: T) -> Error
52 where
53 T: Display,
54 {
55 Error::Message(msg.to_string())
56 }
57
58 pub(crate) fn serde<E>(err: E) -> Error
59 where
60 E: Into<Box<dyn StdError + Send + Sync>>,
61 {
62 Error::Serde(err.into())
63 }
64
65 pub(crate) fn io<E>(err: E) -> Error
66 where
67 E: Into<io::Error>,
68 {
69 Error::Io(err.into())
70 }
71
72 pub(crate) fn glob_pattern<T>(pattern: T, source: glob::PatternError) -> Error
73 where
74 T: Display,
75 {
76 Error::GlobPatternError {
77 pattern: pattern.to_string(),
78 source,
79 }
80 }
81}
82
83impl From<serde_json::Error> for Error {
84 fn from(err: serde_json::Error) -> Self {
85 if err.is_io() {
86 Error::io(err)
87 } else {
88 Error::serde(err)
89 }
90 }
91}
92
93impl From<serde_yaml::Error> for Error {
94 fn from(err: serde_yaml::Error) -> Self {
95 if let Some(source) = err.source() {
96 if let Some(io_err) = source.downcast_ref::<io::Error>() {
97 return Error::io(io_err.kind());
98 }
99 }
100
101 Error::serde(err)
102 }
103}
104
105impl From<json5::Error> for Error {
106 fn from(err: json5::Error) -> Self {
107 Error::serde(err)
108 }
109}
110
111impl From<toml::ser::Error> for Error {
112 fn from(err: toml::ser::Error) -> Self {
113 Error::serde(err)
114 }
115}
116
117impl From<toml::de::Error> for Error {
118 fn from(err: toml::de::Error) -> Self {
119 Error::serde(err)
120 }
121}
122
123impl From<csv::Error> for Error {
124 fn from(err: csv::Error) -> Self {
125 if err.is_io_error() {
126 match err.into_kind() {
127 csv::ErrorKind::Io(io_err) => Error::io(io_err),
128 _ => unreachable!(),
129 }
130 } else {
131 Error::serde(err)
132 }
133 }
134}
135
136impl From<serde_qs::Error> for Error {
137 fn from(err: serde_qs::Error) -> Self {
138 match err {
139 serde_qs::Error::Io(io_err) => Error::io(io_err),
140 other => Error::serde(other),
141 }
142 }
143}
144
145impl From<serde_xml_rs::Error> for Error {
146 fn from(err: serde_xml_rs::Error) -> Self {
147 match err {
148 serde_xml_rs::Error::Io { source } => Error::io(source),
149 other => Error::serde(other),
150 }
151 }
152}
153
154impl From<hcl::Error> for Error {
155 fn from(err: hcl::Error) -> Self {
156 match err {
157 hcl::Error::Io(io_err) => Error::io(io_err),
158 other => Error::serde(other),
159 }
160 }
161}