use core::fmt;
#[cfg(not(feature = "std"))]
use crate::alloc_prelude::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
Unknown(String),
MissingValue(String),
MissingRequired(String),
UnexpectedPositional(String),
UnexpectedValue(String),
UnknownSubcommand(String),
MissingSubcommand,
Value {
arg: String,
value: String,
msg: String,
},
Conflict {
group: String,
first: String,
second: String,
},
MissingGroup { group: String, options: String },
Help(String),
Version(String),
}
impl Error {
#[must_use]
pub const fn is_exit(&self) -> bool {
matches!(*self, Self::Help(_) | Self::Version(_))
}
#[cfg(feature = "std")]
pub fn exit(self) -> ! {
match self {
Self::Help(text) | Self::Version(text) => {
println!("{text}");
std::process::exit(0);
},
other => {
eprintln!("error: {other}");
std::process::exit(2);
},
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Unknown(a) => write!(f, "unrecognised argument '{a}'"),
Self::MissingValue(a) => write!(f, "'{a}' needs a value"),
Self::MissingRequired(a) => write!(f, "missing required argument {a}"),
Self::UnexpectedPositional(v) => write!(f, "unexpected argument '{v}'"),
Self::UnexpectedValue(a) => write!(f, "'{a}' does not take a value"),
Self::UnknownSubcommand(s) => write!(f, "unknown subcommand '{s}'"),
Self::MissingSubcommand => write!(f, "a subcommand is required"),
Self::Value { arg, value, msg } => {
write!(f, "invalid value '{value}' for {arg}: {msg}")
},
Self::Conflict {
group,
first,
second,
} => {
if group.is_empty() {
write!(f, "{first} and {second} cannot be used together")
} else {
write!(f, "{first} and {second} cannot be used together ({group})")
}
},
Self::MissingGroup { group, options } => {
write!(f, "one of {options} is required ({group})")
},
Self::Help(text) | Self::Version(text) => write!(f, "{text}"),
}
}
}
impl core::error::Error for Error {}