error reporting

This commit is contained in:
nora 2021-10-01 23:47:16 +02:00
parent d2788c133c
commit 34bddb59a6
4 changed files with 52 additions and 12 deletions

View file

@ -7,7 +7,11 @@ arg!(OLevel: "optimize" -> usize);
fn main() {
let args = badargs::badargs!(OutFile, Force, OLevel);
let _outfile = args.get::<OutFile>();
let _force = args.get::<Force>();
let _o_level = args.get::<OLevel>();
let outfile = args.get::<OutFile>();
let force = args.get::<Force>();
let o_level = args.get::<OLevel>();
println!("output: {:?}", outfile);
println!("force: {:?}", force);
println!("o-level: {:?}", o_level);
}

View file

@ -32,6 +32,7 @@
mod macros;
mod parse;
mod reporting;
mod schema;
use crate::parse::CliArgs;
@ -56,9 +57,11 @@ where
{
let arg_schema = Schema::create::<S>().expect("Invalid schema!");
let args = CliArgs::from_args(&arg_schema, std::env::args()).expect("todo");
BadArgs { args }
let args = CliArgs::from_args(&arg_schema, std::env::args());
match args {
Ok(args) => BadArgs { args },
Err(err) => reporting::report(err),
}
}
///
@ -89,6 +92,11 @@ impl BadArgs {
let long_name = T::long();
self.args.get::<T::Content>(long_name)
}
/// Get all unnamed additional arguments
pub fn unnamed(&self) -> &[String] {
self.args.unnamed()
}
}
///
@ -123,6 +131,8 @@ mod sealed {
}
mod error {
use crate::schema::SchemaKind;
/// Invalid schema
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum SchemaError {
@ -133,10 +143,9 @@ mod error {
/// Invalid arguments provided
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum CallError {
SingleMinus,
ShortFlagNotFound(char),
LongFlagNotFound(String),
ExpectedValue(String),
ExpectedValue(String, SchemaKind),
INan(String),
UNan(String),
CombinedShortWithValue(String),

View file

@ -65,7 +65,8 @@ fn parse_shorts(
parse_value(command.kind, results, &command.long, args)?;
} else {
return Err(CallError::SingleMinus);
// '-' is a valid argument, like the `cat -`
results.unnamed.push("-".to_string());
}
for flag in all_shorts {
@ -106,13 +107,13 @@ fn parse_value(
SchemaKind::String => {
let string = args
.next()
.ok_or_else(|| CallError::ExpectedValue(long.to_string()))?;
.ok_or_else(|| CallError::ExpectedValue(long.to_string(), kind))?;
results.insert(long, Box::new(string));
}
SchemaKind::INum => {
let integer = args
.next()
.ok_or_else(|| CallError::ExpectedValue(long.to_string()))?
.ok_or_else(|| CallError::ExpectedValue(long.to_string(), kind))?
.parse::<isize>()
.map_err(|_| CallError::INan(long.to_string()))?;
results.insert(long, Box::new(integer))
@ -120,7 +121,7 @@ fn parse_value(
SchemaKind::UNum => {
let integer = args
.next()
.ok_or_else(|| CallError::ExpectedValue(long.to_string()))?
.ok_or_else(|| CallError::ExpectedValue(long.to_string(), kind))?
.parse::<usize>()
.map_err(|_| CallError::UNan(long.to_string()))?;
results.insert(long, Box::new(integer))

26
src/reporting.rs Normal file
View file

@ -0,0 +1,26 @@
use crate::error::CallError;
use crate::schema::SchemaKind;
pub fn report(err: CallError) -> ! {
match err {
CallError::ShortFlagNotFound(arg) => println!("error: argument '{}' does not exist.", arg),
CallError::LongFlagNotFound(arg) => println!("error: argument '{}' does not exist.", arg),
CallError::ExpectedValue(arg, kind) => {
println!(
"error: argument '{}' expected {} value, but got nothing.",
arg,
match kind {
SchemaKind::String => "string",
SchemaKind::Bool => unreachable!(),
SchemaKind::INum => "integer",
SchemaKind::UNum => "positive integer",
}
)
}
CallError::INan(arg) => println!("error: argument '{}' expected a positive integer value, but got an invalid positive integer.", arg),
CallError::UNan(arg) => println!("error: argument '{}' expected an integer value, but got an invalid integer.", arg),
CallError::CombinedShortWithValue(arg) => println!("error: using argument expecting value '{}' in position where only flags are allowed", arg)
}
std::process::exit(1)
}