-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy patherror.rs
More file actions
152 lines (127 loc) · 4.24 KB
/
Copy patherror.rs
File metadata and controls
152 lines (127 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! [thiserror] implementation
use thiserror::Error as ThisError;
#[cfg(feature = "colored")]
use colored::Colorize;
const RATE_LIMIT: &str = "we might be getting rate-limited here";
const CONFIG_PATHS: &str = "config file locations:
./nvrs.toml
$XDG_CONFIG_HOME/nvrs/nvrs.toml
$HOME/.config/nvrs.toml";
const NOT_EMPTY: &str = "make sure the file is not empty";
const EXAMPLE_CONFIG_TABLE: &str = "example:
[__config__]
oldver = \"oldver.json\"
newver = \"newver.json\"";
/// custom Error type for nvrs
#[derive(Debug, ThisError)]
pub enum Error {
/// [reqwest] errors
#[error("request error: {0}")]
RequestError(#[from] reqwest::Error),
/// [std::io] errors
#[error("io error: {0}")]
IOError(#[from] std::io::Error),
/// [serde_json] errors
#[error("json parsing error: {0}")]
JSONError(#[from] serde_json::Error),
/// [toml::de] errors
#[error("toml parsing error: {0}")]
TOMLError(#[from] toml::de::Error),
/// [toml::ser] errors
#[error("toml parsing error: {0}")]
TOMLErrorSer(#[from] toml::ser::Error),
/// [std::env] errors
#[error("env error: {0}")]
EnvError(#[from] std::env::VarError),
// custom errors
/// request status != OK
#[error("{0}: request status != OK\n{1}")]
RequestNotOK(String, String),
/// request status == 430
#[error("{0}: request returned 430\n{RATE_LIMIT}")]
RequestForbidden(String),
/// latest version of a package not found
#[error("{0}: version not found")]
NoVersion(String),
/// specified configuration file not found
#[error("specified config file not found")]
NoConfigSpecified,
/// configuration file not found in any of the default locations
#[error("no config found\n{CONFIG_PATHS}\n{NOT_EMPTY}")]
NoConfig,
/// no `__config__` in the configuration file
#[error("__config__ not specified\n{EXAMPLE_CONFIG_TABLE}")]
NoConfigTable,
/// keyfile specified in the configuration not found
#[error("specified keyfile not found\n{NOT_EMPTY}")]
NoKeyfile,
/// no `oldver` or `newver` in `__config__`
#[error("oldver & newver not specified\n{EXAMPLE_CONFIG_TABLE}")]
NoXVer,
/// unsupported verfile version
#[error("unsupported verfile version\nplease update your verfiles")]
VerfileVer,
/// package not found in newver
#[error("{0}: package not in newver")]
PkgNotInNewver(String),
/// package not found in config
#[error("{0}: package not in config")]
PkgNotInConfig(String),
/// source / API not found
#[error("source {0} not found")]
SourceNotFound(String),
/// shell command failed
#[error("shell command failed: {0}")]
ShellCommandFailed(String),
}
impl Error {
/// display a pretty formatted error message
/// # example usage
/// ```rust
/// use nvrs::error;
///
/// let config_err = error::Error::NoConfig;
/// let source_err = error::Error::SourceNotFound("github".to_string());
///
///println!("config error:\n");
/// config_err.pretty();
///println!("\n\nsource error:\n");
/// source_err.pretty();
/// ```
/// the above example will result in:
/// [image](https://imgur.com/a/4SZeFXn)
#[cfg(feature = "colored")]
pub fn pretty(&self) {
let mut lines: Vec<String> = self
.to_string()
.lines()
.map(|line| line.to_string())
.collect();
let first = lines.remove(0);
let first_split = first.split_once(':').unwrap_or(("", &first));
if first_split.0.is_empty() {
println!("{} {}", "!".red().bold().on_black(), first_split.1.red());
} else {
println!(
"{} {}:{}",
"!".red().bold().on_black(),
first_split.0,
first_split.1.red()
);
}
for line in lines {
println!("{} {}", "!".red().on_black(), line)
}
}
}
/// custom Result type for nvrs
pub type Result<T> = std::result::Result<T, Error>;
#[test]
fn test_error() {
let message = "nvrs died. now why could that be...?";
let error = Error::from(std::io::Error::other(message));
assert_eq!(
format!("\"io error: {message}\""),
format!("{:?}", error.to_string())
)
}