Now returns an error when not all program args are passed via command-line

There was a lot of stuff added here. The most important addition is
how Pirate now returns a MissingArgument kinded error if a required
program argument isn't passed to the program.
This commit is contained in:
Zach Dziura 2015-04-30 15:14:34 +00:00
parent da684ab0f7
commit 25327fa441
5 changed files with 25 additions and 14 deletions

View file

@ -13,9 +13,10 @@ Ever.
In all seriousness, `getopts` is a fantastic library that gives the developers all of the tools
necessary to create and interface with command-line arguments. However, with all that power comes
complexity. `getopts`, while straight forward to use, is verbose. The developer has to make repeated
method calls to add different command-line options. And while the only victim here is the
developer's wrists due to carpal tunnel, I felt that there was a better way to do things.
complexity. `getopts` -- while straight forward to use -- is verbose. The developer has to call
different functions repeatedly in order to add different command-line options to their programs. And
while the only victim here is the developer's wrists due to carpal tunnel, I felt that there was a
better way to do things.
Enter Pirate (which should totally usurp `getopts` for the award of Most Originally Named Project Ever).
@ -32,7 +33,7 @@ pirate = "0.1.0"
and this to your crate root:
```rust
extern crate getopts;
extern crate pirate;
```
Usage
@ -145,7 +146,7 @@ To Do
- [ ] Create a helper function for generating `--help` output, rather than having the user create it
manually.
- [ ] Also create helper functions for defining the description section of the `--help` output.
- [ ] Refactor the `ErrorKind` enum into a struct that is able to represent more complex data (such
- [x] Refactor the `ErrorKind` enum into a struct that is able to represent more complex data (such
giving the value of the invalid argument passed to the program).
License

View file

@ -28,34 +28,36 @@ pub struct Error {
impl Error {
pub fn new(kind: ErrorKind, offender: String) -> Error {
Error {
kind: kind,
offender: offender,
kind: kind.clone(),
offender: offender.clone(),
desc: format!("{} {}", kind.description(), offender.clone()),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
&format!("{} {}", self.kind.description(), self.offender);
&self.desc
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "{}", self.description())
write!(f, "{}", self.desc)
}
}
#[derive(Clone, Debug)]
pub enum ErrorKind {
InvalidOption,
MissingArgument,
}
impl ErrorKind {
fn description(&self) -> &str {
fn description(&self) -> String {
match *self {
ErrorKind::InvalidOption => "An invalid option was passed to the program:",
ErrorKind::MissingArgument => "A required argument is missing:",
ErrorKind::InvalidOption => String::from("An invalid option was passed to the program:"),
ErrorKind::MissingArgument => String::from("A required argument is missing:"),
}
}
}

View file

@ -25,7 +25,7 @@ pub use errors::{Error, ErrorKind};
pub use matches::Matches;
use opts::Opts;
pub fn parse(mut args: Args, options: &[&'static str]) -> Result<Matches, ErrorKind> {
pub fn parse(mut args: Args, options: &[&'static str]) -> Result<Matches, Error> {
let mut matches: Matches = Matches::new();
let mut opts: Opts = opts(options); // Jesus, this is redundant...
@ -73,7 +73,10 @@ pub fn parse(mut args: Args, options: &[&'static str]) -> Result<Matches, ErrorK
next_arg = args.next();
}
Ok(matches)
match opts.arg_len() {
0 => Ok(matches),
_ => Err(Error::new(ErrorKind::MissingArgument, opts.get_arg().unwrap())),
}
}
fn opts(opts: &[&'static str]) -> Opts {

View file

@ -50,4 +50,8 @@ impl Opts {
pub fn get_arg(&mut self) -> Option<String> {
self.args.pop_front()
}
pub fn arg_len(&self) -> usize {
self.args.len()
}
}

View file

@ -23,6 +23,7 @@ fn main() {
}
let input = matches.get("input").unwrap().parse::<i32>().unwrap();
let num = match matches.get("n") {
Some(n) => n.parse::<i32>().unwrap(),
None => 1