1use std::fmt::Display;
2
3use serde_yaml::Location;
4use thiserror::Error;
5
6pub type Result<T, E = Error> = std::result::Result<T, E>;
7
8#[derive(Error, Debug)]
9pub enum Error {
10 #[error("Error while deserializing the document{loc}: {0}", loc = location_into(.0.location()))]
11 Deserialize(#[from] serde_yaml::Error),
12 #[error("Error while parsing: {0}")]
13 ParseFromStr(#[from] serde::de::value::Error),
14 #[error("{0}")]
15 Format(#[from] std::fmt::Error),
16 #[error("{e}", e = report(.0))]
17 Reqwest(#[from] reqwest::Error),
18 #[error("{0}")]
19 Custom(String),
20}
21
22impl Error {
23 pub fn display<S: Display>(error: S) -> Self {
24 Self::Custom(format!("{}", error))
25 }
26}
27
28fn location_into(location: Option<Location>) -> String {
29 location
30 .map(|location| format!(" at line {}, column {}", location.line(), location.column()))
31 .unwrap_or_else(|| "".into())
32}
33
34fn report(mut err: &dyn std::error::Error) -> String {
35 let mut s = format!("{}", err);
36 while let Some(src) = err.source() {
37 s.push_str(format!("\n\tCaused by: {}", src).as_str());
38 err = src;
39 }
40 s
41}