pipelight_error/
lib.rs

1use miette::{Diagnostic, Report, SourceOffset, SourceSpan};
2use thiserror::Error;
3
4#[derive(Debug, Error, Diagnostic)]
5pub enum PipelightError {
6    #[error(transparent)]
7    #[diagnostic(code(pipelight::io::error))]
8    IoError(#[from] std::io::Error),
9
10    #[error(transparent)]
11    #[diagnostic(transparent)]
12    WrapError(#[from] WrapError),
13
14    #[error(transparent)]
15    #[diagnostic(transparent)]
16    LibError(#[from] LibError),
17
18    #[error(transparent)]
19    #[diagnostic(transparent)]
20    CastError(#[from] CastError),
21}
22
23/**
24A config error with help higher origin
25Can be recursively chained.
26*/
27#[derive(Debug, Error, Diagnostic)]
28#[error("{}", message)]
29#[diagnostic(code(pipelight::wrap::error))]
30pub struct WrapError {
31    pub message: String,
32    #[diagnostic_source]
33    pub origin: Report,
34    #[help]
35    pub help: String,
36}
37
38/**
39A root cause error with no inner origin
40*/
41#[derive(Debug, Error, Diagnostic)]
42#[error("{}", message)]
43#[diagnostic(code(pipelight::lib::error))]
44pub struct LibError {
45    pub message: String,
46    #[help]
47    pub help: String,
48}
49
50#[derive(Error, Diagnostic, Debug)]
51pub enum CastError {
52    // Deserialize
53    #[error(transparent)]
54    #[diagnostic(transparent)]
55    JsonError(#[from] JsonError),
56
57    #[error(transparent)]
58    #[diagnostic(transparent)]
59    YamlError(#[from] YamlError),
60
61    #[error(transparent)]
62    #[diagnostic(transparent)]
63    TomlError(#[from] TomlError),
64
65    #[error(transparent)]
66    #[diagnostic(transparent)]
67    HclError(#[from] HclError),
68
69    // Serialize
70    #[error(transparent)]
71    #[diagnostic(code(serialize::toml))]
72    TomlSerError(#[from] toml::ser::Error),
73}
74
75/**
76A JSON report type with hint, colors and code span.
77For better configuration file debugging
78*/
79#[derive(Error, Diagnostic, Debug)]
80#[diagnostic(code(cast::json))]
81#[error("Serde: Could not convert Json into Rust types")]
82pub struct JsonError {
83    #[source]
84    pub origin: serde_json::Error,
85    #[label("here")]
86    pub at: SourceSpan,
87    #[source_code]
88    pub src: String,
89}
90impl JsonError {
91    pub fn new(e: serde_json::Error, src: &str) -> Self {
92        JsonError {
93            at: SourceSpan::new(
94                SourceOffset::from_location(
95                    //source
96                    src,
97                    e.line(),
98                    e.column(),
99                ),
100                1,
101            ),
102            src: src.to_owned(),
103            origin: e,
104        }
105    }
106}
107
108/**
109A TOML report type with hint, colors and code span.
110For better configuration file debugging
111*/
112#[derive(Error, Diagnostic, Debug)]
113#[diagnostic(code(cast::toml))]
114#[error("Serde: Could not convert Toml into Rust types")]
115pub struct TomlError {
116    #[source]
117    pub origin: toml::de::Error,
118    #[label("here")]
119    pub at: SourceSpan,
120    #[source_code]
121    pub src: String,
122}
123impl TomlError {
124    pub fn new(e: toml::de::Error, src: &str) -> Self {
125        if let Some(span) = e.span() {
126            let line = span.start;
127            let column = span.end;
128            TomlError {
129                at: SourceSpan::new(
130                    SourceOffset::from_location(
131                        //source
132                        src, line, column,
133                    ),
134                    1,
135                ),
136                src: src.to_owned(),
137                origin: e,
138            }
139        } else {
140            TomlError {
141                at: SourceSpan::new(0.into(), 0),
142                src: src.to_owned(),
143                origin: e,
144            }
145        }
146    }
147}
148
149/**
150A Hcl report type with hint, colors and code span.
151For better configuration file debugging
152*/
153#[derive(Error, Diagnostic, Debug)]
154#[diagnostic(code(cast::hcl))]
155#[error("Serde: Could not convert Hcl into Rust types")]
156pub struct HclError {
157    #[source]
158    pub origin: hcl::Error,
159    #[label("here")]
160    pub at: SourceSpan,
161    #[source_code]
162    pub src: String,
163}
164impl HclError {
165    pub fn new(e: hcl::Error, src: &str) -> Self {
166        match e {
167            hcl::Error::Parse(e) => {
168                let line = e.location().line();
169                let column = e.location().column();
170                HclError {
171                    at: SourceSpan::new(
172                        SourceOffset::from_location(
173                            //source
174                            src, line, column,
175                        ),
176                        1,
177                    ),
178                    src: src.to_owned(),
179                    origin: hcl::Error::from(e),
180                }
181            }
182            _ => HclError {
183                at: SourceSpan::new(0.into(), 0),
184                src: src.to_owned(),
185                origin: e,
186            },
187        }
188    }
189}
190
191/**
192A YAML report type with hint, colors and code span.
193For better configuration file debugging
194*/
195#[derive(Error, Diagnostic, Debug)]
196#[diagnostic(code(cast::yaml))]
197#[error("Serde: Could not convert Yaml into Rust types")]
198pub struct YamlError {
199    #[source]
200    pub origin: serde_yaml::Error,
201    #[label("here")]
202    pub at: SourceSpan,
203    #[source_code]
204    pub src: String,
205}
206impl YamlError {
207    pub fn new(e: serde_yaml::Error, src: &str) -> Self {
208        if let Some(location) = e.location() {
209            let line = location.line();
210            let column = location.column();
211            YamlError {
212                at: SourceSpan::new(
213                    SourceOffset::from_location(
214                        //source
215                        src, line, column,
216                    ),
217                    1,
218                ),
219                src: src.to_owned(),
220                origin: e,
221            }
222        } else {
223            YamlError {
224                at: SourceSpan::new(0.into(), 0),
225                src: src.to_owned(),
226                origin: e,
227            }
228        }
229    }
230}