1use std::process::ExitCode;
2
3use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum AppError {
7 #[error("invalid input: {0}")]
8 InvalidInput(String),
9 #[error("{platform} does not support `{feature}` yet")]
10 UnsupportedPlatformFeature { platform: String, feature: String },
11 #[error("network error: {0}")]
12 Network(String),
13 #[error("parse error: {0}")]
14 Parse(String),
15 #[error("no usable public data found")]
16 NoPublicData,
17 #[error("io error: {0}")]
18 Io(#[from] std::io::Error),
19 #[error("request error: {0}")]
20 Request(#[from] reqwest::Error),
21 #[error("url error: {0}")]
22 Url(#[from] url::ParseError),
23 #[error("json error: {0}")]
24 Json(#[from] serde_json::Error),
25 #[error("csv error: {0}")]
26 Csv(#[from] csv::Error),
27 #[error("toml error: {0}")]
28 Toml(#[from] toml::de::Error),
29}
30
31pub type Result<T> = std::result::Result<T, AppError>;
32
33impl AppError {
34 pub fn exit_code(&self) -> i32 {
35 match self {
36 Self::NoPublicData => 2,
37 _ => 1,
38 }
39 }
40}
41
42impl From<anyhow::Error> for AppError {
43 fn from(value: anyhow::Error) -> Self {
44 Self::Parse(value.to_string())
45 }
46}
47
48impl From<ExitCode> for AppError {
49 fn from(_: ExitCode) -> Self {
50 Self::Parse("process exited unexpectedly".to_string())
51 }
52}