use clap::error::ErrorKind;
#[derive(Clone, Debug, thiserror::Error)]
pub enum Error {
#[error("There is no valid config directory")]
ConfigDir,
#[error("Unable to build a valid configuration")]
ConfigBuild,
#[error("Unable to deserialize config")]
ConfigDeserialize,
#[error("There is no valid data directory")]
DataDir,
#[error("Unable to read the certificate file")]
CertRead,
#[error("Unable to read the private key file")]
KeyRead,
#[error("No valid private keys found in the key file")]
NoPrivateKeys,
#[error("no valid captures")]
NoValidCaptures,
#[error("invalid range: '{}'", .0)]
InvalidRange(String),
#[error("invalid first capture")]
InvalidFirstCapture,
#[error("invalid second capture")]
InvalidSecondCapture,
#[error("invalid time string: '{}'", .0)]
InvalidTime(String),
#[error("invalid date string: '{}'", .0)]
InvalidDate(String),
#[error("invalid calendar string: '{}'", .0)]
InvalidCalendar(String),
#[error("invalid query type")]
InvalidQueryType,
#[error("invalid update kind: '{}'", kind)]
InvalidUpdateKind {
kind: String,
},
#[error("invalid day of week: '{}'", .0)]
InvalidDayOfWeek(String),
#[error("invalid year: '{}'", .0)]
InvalidYear(String),
#[error("invalid month: '{}'", .0)]
InvalidMonth(String),
#[error("invalid day: '{}'", .0)]
InvalidDay(String),
#[error("invalid month of year: '{}'", .0)]
InvalidMonthOfYear(String),
#[error("invalid day of month: '{}'", .0)]
InvalidDayOfMonth(String),
#[error("invalid hour of day: '{}'", .0)]
InvalidHourOfDay(String),
#[error("invalid minute of hour: '{}'", .0)]
InvalidMinuteOfHour(String),
#[error("invalid second of minute: '{}'", .0)]
InvalidSecondOfMinute(String),
}
#[allow(clippy::needless_pass_by_value)]
#[must_use]
pub fn clap_or_error(err: anyhow::Error) -> i32 {
let disp_err = || {
eprintln!("{err:?}");
1
};
match err.downcast_ref::<clap::Error>() {
Some(e) => match e.kind() {
ErrorKind::DisplayHelp | ErrorKind::DisplayVersion => {
println!("{e}");
0
}
ErrorKind::InvalidValue
| ErrorKind::UnknownArgument
| ErrorKind::InvalidSubcommand
| ErrorKind::NoEquals
| ErrorKind::ValueValidation
| ErrorKind::TooManyValues
| ErrorKind::TooFewValues
| ErrorKind::WrongNumberOfValues
| ErrorKind::ArgumentConflict
| ErrorKind::MissingRequiredArgument
| ErrorKind::MissingSubcommand
| ErrorKind::InvalidUtf8
| ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand
| ErrorKind::Io
| ErrorKind::Format => disp_err(),
_ => unknown_err_kind(),
},
None => disp_err(),
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
fn unknown_err_kind() -> i32 {
eprintln!("Unknown ErrorKind");
1
}
#[must_use]
pub fn success((): ()) -> i32 {
0
}
#[cfg(test)]
mod test {
use super::{clap_or_error, success};
use anyhow::{Error, anyhow};
use clap::{
Command,
error::ErrorKind::{self, DisplayHelp, DisplayVersion},
};
#[test]
fn test_success() {
assert_eq!(success(()), 0);
}
#[test]
fn clap_or_error_is_error() {
assert_eq!(1, clap_or_error(anyhow!("test")));
}
#[test]
fn clap_or_error_is_help() {
let mut cmd = Command::new("bartos");
let error = cmd.error(DisplayHelp, "help");
let clap_error = Error::new(error);
assert_eq!(0, clap_or_error(clap_error));
}
#[test]
fn clap_or_error_is_version() {
let mut cmd = Command::new("bartos");
let error = cmd.error(DisplayVersion, "1.0");
let clap_error = Error::new(error);
assert_eq!(0, clap_or_error(clap_error));
}
#[test]
fn clap_or_error_is_other_clap_error() {
let mut cmd = Command::new("bartos");
let error = cmd.error(ErrorKind::InvalidValue, "Some failure case");
let clap_error = Error::new(error);
assert_eq!(1, clap_or_error(clap_error));
}
}