mirror of
https://github.com/Noratrieb/badargs.git
synced 2026-01-14 11:55:00 +01:00
float support and simple help
This commit is contained in:
parent
3fb8953ff4
commit
37ba39863a
6 changed files with 56 additions and 15 deletions
|
|
@ -36,6 +36,7 @@ The following return types are currently available:
|
||||||
* bool
|
* bool
|
||||||
* isize
|
* isize
|
||||||
* usize
|
* usize
|
||||||
|
* f64
|
||||||
|
|
||||||
Boolean values can only be `None` or `Some`.
|
Boolean values can only be `None` or `Some`.
|
||||||
The other values can be `None` or `Some(_)`
|
The other values can be `None` or `Some(_)`
|
||||||
|
|
|
||||||
15
src/lib.rs
15
src/lib.rs
|
|
@ -37,10 +37,10 @@ mod schema;
|
||||||
|
|
||||||
use crate::parse::CliArgs;
|
use crate::parse::CliArgs;
|
||||||
use crate::schema::{IntoSchema, Schema, SchemaKind};
|
use crate::schema::{IntoSchema, Schema, SchemaKind};
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
pub use error::SchemaError;
|
pub use error::SchemaError;
|
||||||
pub use macros::*;
|
pub use macros::*;
|
||||||
use std::any::Any;
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, SchemaError>;
|
pub type Result<T> = std::result::Result<T, SchemaError>;
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ where
|
||||||
let args = CliArgs::from_args(&arg_schema, std::env::args_os());
|
let args = CliArgs::from_args(&arg_schema, std::env::args_os());
|
||||||
match args {
|
match args {
|
||||||
Ok(args) => BadArgs { args },
|
Ok(args) => BadArgs { args },
|
||||||
Err(err) => reporting::report(err),
|
Err(err) => reporting::report(err, &arg_schema),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,7 +106,7 @@ pub trait CliReturnValue: sealed::SealedCliReturnValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_cli_return {
|
macro_rules! impl_cli_return {
|
||||||
($(for $ty:ty => $type:ident);+) => {$(
|
($(for $ty:ty => $type:ident);+;) => {$(
|
||||||
impl CliReturnValue for $ty {
|
impl CliReturnValue for $ty {
|
||||||
fn kind() -> SchemaKind {
|
fn kind() -> SchemaKind {
|
||||||
SchemaKind::$type
|
SchemaKind::$type
|
||||||
|
|
@ -118,8 +118,9 @@ macro_rules! impl_cli_return {
|
||||||
impl_cli_return!(
|
impl_cli_return!(
|
||||||
for String => String;
|
for String => String;
|
||||||
for bool => Bool;
|
for bool => Bool;
|
||||||
for isize => INum;
|
for isize => IInt;
|
||||||
for usize => UNum
|
for usize => UInt;
|
||||||
|
for f64 => Num;
|
||||||
);
|
);
|
||||||
|
|
||||||
mod sealed {
|
mod sealed {
|
||||||
|
|
@ -127,7 +128,7 @@ mod sealed {
|
||||||
macro_rules! impl_ {
|
macro_rules! impl_ {
|
||||||
($($name:ty),+) => {$(impl SealedCliReturnValue for $name{})+};
|
($($name:ty),+) => {$(impl SealedCliReturnValue for $name{})+};
|
||||||
}
|
}
|
||||||
impl_!(String, bool, usize, isize);
|
impl_!(String, bool, usize, isize, f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
mod error {
|
mod error {
|
||||||
|
|
@ -149,7 +150,9 @@ mod error {
|
||||||
ExpectedValue(String, SchemaKind),
|
ExpectedValue(String, SchemaKind),
|
||||||
INan(String),
|
INan(String),
|
||||||
UNan(String),
|
UNan(String),
|
||||||
|
NNan(String),
|
||||||
CombinedShortWithValue(String),
|
CombinedShortWithValue(String),
|
||||||
InvalidUtf8(OsString),
|
InvalidUtf8(OsString),
|
||||||
|
HelpPage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! arg {
|
macro_rules! arg {
|
||||||
// implicit optional
|
|
||||||
($name:ident: $long:literal, $short:literal -> $result:ty) => {
|
($name:ident: $long:literal, $short:literal -> $result:ty) => {
|
||||||
arg!(@$name: ($long, ::std::option::Option::Some($short)) -> $result);
|
arg!(@$name: ($long, ::std::option::Option::Some($short)) -> $result);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
17
src/parse.rs
17
src/parse.rs
|
|
@ -93,6 +93,9 @@ fn parse_long(
|
||||||
long: &str,
|
long: &str,
|
||||||
args: &mut impl Iterator<Item = OsString>,
|
args: &mut impl Iterator<Item = OsString>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
if long == "help" {
|
||||||
|
return Err(CallError::HelpPage);
|
||||||
|
}
|
||||||
let command = schema
|
let command = schema
|
||||||
.long(long)
|
.long(long)
|
||||||
.ok_or_else(|| CallError::LongFlagNotFound(long.to_string()))?;
|
.ok_or_else(|| CallError::LongFlagNotFound(long.to_string()))?;
|
||||||
|
|
@ -115,7 +118,7 @@ fn parse_value(
|
||||||
.map_err(CallError::InvalidUtf8)?;
|
.map_err(CallError::InvalidUtf8)?;
|
||||||
results.insert(long, Box::new(string));
|
results.insert(long, Box::new(string));
|
||||||
}
|
}
|
||||||
SchemaKind::INum => {
|
SchemaKind::IInt => {
|
||||||
let integer = args
|
let integer = args
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| CallError::ExpectedValue(long.to_string(), kind))?
|
.ok_or_else(|| CallError::ExpectedValue(long.to_string(), kind))?
|
||||||
|
|
@ -125,7 +128,7 @@ fn parse_value(
|
||||||
.map_err(|_| CallError::INan(long.to_string()))?;
|
.map_err(|_| CallError::INan(long.to_string()))?;
|
||||||
results.insert(long, Box::new(integer))
|
results.insert(long, Box::new(integer))
|
||||||
}
|
}
|
||||||
SchemaKind::UNum => {
|
SchemaKind::UInt => {
|
||||||
let integer = args
|
let integer = args
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| CallError::ExpectedValue(long.to_string(), kind))?
|
.ok_or_else(|| CallError::ExpectedValue(long.to_string(), kind))?
|
||||||
|
|
@ -135,6 +138,16 @@ fn parse_value(
|
||||||
.map_err(|_| CallError::UNan(long.to_string()))?;
|
.map_err(|_| CallError::UNan(long.to_string()))?;
|
||||||
results.insert(long, Box::new(integer))
|
results.insert(long, Box::new(integer))
|
||||||
}
|
}
|
||||||
|
SchemaKind::Num => {
|
||||||
|
let float = args
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| CallError::ExpectedValue(long.to_string(), kind))?
|
||||||
|
.into_string()
|
||||||
|
.map_err(CallError::InvalidUtf8)?
|
||||||
|
.parse::<f64>()
|
||||||
|
.map_err(|_| CallError::NNan(long.to_string()))?;
|
||||||
|
results.insert(long, Box::new(float))
|
||||||
|
}
|
||||||
SchemaKind::Bool => {
|
SchemaKind::Bool => {
|
||||||
results.insert(long, Box::new(true));
|
results.insert(long, Box::new(true));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::error::CallError;
|
use crate::error::CallError;
|
||||||
use crate::schema::SchemaKind;
|
use crate::schema::{Schema, SchemaKind};
|
||||||
|
|
||||||
pub fn report(err: CallError) -> ! {
|
pub fn report(err: CallError, schema: &Schema) -> ! {
|
||||||
match err {
|
match err {
|
||||||
CallError::ShortFlagNotFound(arg) => println!("error: argument '{}' does not exist.", arg),
|
CallError::ShortFlagNotFound(arg) => println!("error: argument '{}' does not exist.", arg),
|
||||||
CallError::LongFlagNotFound(arg) => println!("error: argument '{}' does not exist.", arg),
|
CallError::LongFlagNotFound(arg) => println!("error: argument '{}' does not exist.", arg),
|
||||||
|
|
@ -12,15 +12,35 @@ pub fn report(err: CallError) -> ! {
|
||||||
match kind {
|
match kind {
|
||||||
SchemaKind::String => "string",
|
SchemaKind::String => "string",
|
||||||
SchemaKind::Bool => unreachable!(),
|
SchemaKind::Bool => unreachable!(),
|
||||||
SchemaKind::INum => "integer",
|
SchemaKind::IInt => "integer",
|
||||||
SchemaKind::UNum => "positive integer",
|
SchemaKind::UInt => "positive integer",
|
||||||
|
SchemaKind::Num => "number"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CallError::INan(arg) => println!("error: argument '{}' expected a positive integer value, but got an invalid positive integer.", arg),
|
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::UNan(arg) => println!("error: argument '{}' expected an integer value, but got an invalid integer.", arg),
|
||||||
|
CallError::NNan(arg) => println!("error: argument '{}' expected a number value, but got an invalid number.", arg),
|
||||||
CallError::CombinedShortWithValue(arg) => println!("error: using argument expecting value '{}' in position where only flags are allowed", arg),
|
CallError::CombinedShortWithValue(arg) => println!("error: using argument expecting value '{}' in position where only flags are allowed", arg),
|
||||||
CallError::InvalidUtf8(os_str) => println!("error: invalid utf8: '{}'", os_str.to_string_lossy()),
|
CallError::InvalidUtf8(os_str) => println!("error: invalid utf8: '{}'", os_str.to_string_lossy()),
|
||||||
|
CallError::HelpPage => {
|
||||||
|
println!("Options:");
|
||||||
|
for option in schema.arguments() {
|
||||||
|
print!("--{} ", option.long);
|
||||||
|
if let Some(short) = option.short {
|
||||||
|
print!("(-{}) ", short);
|
||||||
|
}
|
||||||
|
match option.kind {
|
||||||
|
SchemaKind::String => print!("[Takes a value]"),
|
||||||
|
SchemaKind::Bool => {}
|
||||||
|
SchemaKind::IInt => print!("[Takes an integer]"),
|
||||||
|
SchemaKind::UInt => print!("[Takes a positive integer]"),
|
||||||
|
SchemaKind::Num => print!("[Takes a number]"),
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::process::exit(1)
|
std::process::exit(1)
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,9 @@ use std::collections::HashMap;
|
||||||
pub enum SchemaKind {
|
pub enum SchemaKind {
|
||||||
String,
|
String,
|
||||||
Bool,
|
Bool,
|
||||||
INum,
|
IInt,
|
||||||
UNum,
|
UInt,
|
||||||
|
Num,
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -63,6 +64,10 @@ impl Schema {
|
||||||
self.longs.get(name)
|
self.longs.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn arguments(&self) -> impl Iterator<Item = &SchemaCommand> {
|
||||||
|
self.longs.values()
|
||||||
|
}
|
||||||
|
|
||||||
fn add_short_command(&mut self, short_name: char, command: SchemaCommand) -> Result<()> {
|
fn add_short_command(&mut self, short_name: char, command: SchemaCommand) -> Result<()> {
|
||||||
if self.shorts.insert(short_name, command).is_some() {
|
if self.shorts.insert(short_name, command).is_some() {
|
||||||
Err(SchemaError::NameAlreadyExists(short_name.to_string()))
|
Err(SchemaError::NameAlreadyExists(short_name.to_string()))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue