argparse-0.2.2/.gitignore010064400037200003720000000001661334216370200135320ustar0000000000000000/.vagga *.o *.so *.rlib /argparse_test /target # examples /greeting /structure /subcommands # Cargo files Cargo.lock argparse-0.2.2/.travis.yml010064400037200003720000000012231334216370200136460ustar0000000000000000sudo: false dist: trusty language: rust cache: - cargo before_cache: - rm -r $TRAVIS_BUILD_DIR/target/debug jobs: include: - os: linux rust: stable - os: linux rust: beta - os: linux rust: nightly # deploy - stage: publish os: linux rust: stable env: # CARGO_TOKEN - secure: "tk6bJEv46YfZwAKYzxn9+afzEb6nGym9lo/YJgjYIolv2qsNyMLlmC8ptRSRTHwOQPd3c54Y9XYP+61miMmWjppQSjJ4yvkUqnyiYzzdxzVM5dNIbXcqO6GbTgE2rIx9BOH0c/qrmw1KW2iz8TChxgQu/vv8pmDL1kmyawVy3EE=" install: true script: true deploy: - provider: script script: 'cargo publish --verbose --token=$CARGO_TOKEN' on: tags: true argparse-0.2.2/Cargo.toml.orig010064400037200003720000000005401334216370200144250ustar0000000000000000[package] name = "argparse" description = "Powerful command-line argument parsing library" license = "MIT" readme = "README.rst" keywords = ["command-line", "cli", "command", "argument"] categories = ["command-line-interface"] homepage = "http://github.com/tailhook/rust-argparse" version = "0.2.2" authors = ["Paul Colomiets "] argparse-0.2.2/Cargo.toml0000644000000015520000000000000107010ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "argparse" version = "0.2.2" authors = ["Paul Colomiets "] description = "Powerful command-line argument parsing library" homepage = "http://github.com/tailhook/rust-argparse" readme = "README.rst" keywords = ["command-line", "cli", "command", "argument"] categories = ["command-line-interface"] license = "MIT" argparse-0.2.2/LICENSE010064400037200003720000000020471334216370200125470ustar0000000000000000Copyright (c) 2014-2015 Paul Colomiets Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. argparse-0.2.2/README.rst010064400037200003720000000235711334216370200132360ustar0000000000000000======== Argparse ======== The ``rust-argparse`` is command-line parsing module for rust. It's inspired by python's ``argparse`` module. Features: * Supports standard (GNU) option conventions * Properly typed values * Automatically generated help and usage messages Importing ========= Edit your Cargo.toml to add ``rust-argparse`` to your project. .. code-block:: rust [dependencies] argparse = "0.2.2" Example ======= The following code is a simple Rust program with command-line arguments: .. code-block:: rust extern crate argparse; use argparse::{ArgumentParser, StoreTrue, Store}; fn main() { let mut verbose = false; let mut name = "World".to_string(); { // this block limits scope of borrows by ap.refer() method let mut ap = ArgumentParser::new(); ap.set_description("Greet somebody."); ap.refer(&mut verbose) .add_option(&["-v", "--verbose"], StoreTrue, "Be verbose"); ap.refer(&mut name) .add_option(&["--name"], Store, "Name for the greeting"); ap.parse_args_or_exit(); } if verbose { println!("name is {}", name); } println!("Hello {}!", name); } Assuming the Rust code above is saved into a file ``greeting.rs``, let's see what we have now:: $ rustc greeting.rs $ ./greeting -h Usage: ./greeting [OPTIONS] Greet somebody. Optional arguments: -h, --help Show this help message and exit -v, --verbose Be verbose --name NAME Name for the greeting $ ./greeting Hello World! $ ./greeting --name Bob Hello Bob! $ ./greeting -v --name Alice name is Alice Hello Alice! Basic Workflow ============== Create ArgumentParser --------------------- The argument parser is created empty and is built incrementally. So we create a mutable variable:: extern crate argparse; use argparse::ArgumentParser; let mut parser = ArgumentParser::new(); Customize --------- There are optional customization methods. The most important one is:: parser.set_description("My command-line utility") The descripion is rewrapped to fit 80 column string nicely. Just like option descriptions. Add Options ----------- The ``refer`` method creates a cell variable, which the result will be written to:: let mut verbose = false; parser.refer(&mut verbose); Next we add an options which control the variable: For example:: parser.refer(&mut verbose) .add_option(&["-v", "--verbose"], StoreTrue, "Be verbose"); You may add multiple options for the same variable:: parser.refer(&mut verbose) .add_option(&["-v", "--verbose"], StoreTrue, "Be verbose") .add_option(&["-q", "--quiet"], StoreFalse, "Be verbose"); Similarly positional arguments are added:: let mut command = String; parser.refer(&mut command) .add_argument("command", Store, "Command to run"); Organizing Options ------------------ It's often useful to organize options into some kind of structure. You can easily borrow variables from the structure into option parser. For example:: struct Options { verbose: bool, } ... let mut options = Options { verbose: false }; parser.refer(&mut options.verbose) .add_option(&["-v"], StoreTrue, "Be verbose"); Parsing Arguments ----------------- All the complex work is done in ``parser.parse_args()``. But there is a simpler option:: parser.parse_args_or_exit() In case you don't want argparse to exit itself, you might use the ``parse_args`` function directly:: use std::process::exit; match parser.parse_args() { Ok(()) => {} Err(x) => { std::process::exit(x); } } ArgumentParser Methods ====================== ``parser.refer(var: &mut T) -> Ref`` Attach the variable to argument parser. The options are added to the returned ``Ref`` object and modify a variable passed to the method. ``parser.add_option(names: &[&str], action: TypedAction, help: &str)`` Add a single option which has no parameters. Most options must be added by ``refer(..)`` and methods on ``Ref`` object (see below). Example:: ap.add_option(&["-V", "--version"], Print(env!("CARGO_PKG_VERSION").to_string()), "Show version"); ``parser.set_description(descr: &str)`` Set description that is at the top of help message. ``parser.stop_on_first_argument(val: bool)`` If called with ``true``, parser will stop searching for options when first non-option (the one doesn't start with ``-``) argument is encountered. This is useful if you want to parse following options with another argparser or external program. ``parser.silence_double_dash(val: bool)`` If called with ``true`` (default), parser will not treat *first* double dash ``--`` as positional argument. Use ``false`` if you need to add some meaning to the ``--`` marker. ``parser.print_usage(name: &str, writer: &mut Write)`` Prints usage string to stderr. ``parser.print_help(name: &str, writer: &mut Write)`` Writes help to ``writer``, used by ``--help`` option internally. ``parser.parse_args()`` Method that does all the dirty work. And returns ``Result`` ``parser.parse_args_or_exit()`` Method that does all the dirty work. And in case of failure just ``exit()`` Variable Reference Methods ========================== The ``argparse::Ref`` object is returned from ``parser.refer()``. The following methods are used to add and customize arguments: ``option.add_option(names: &[&str], action: TypedAction, help: &str)`` Add an option. All items in names should be either in format ``-X`` or ``--long-option`` (i.e. one dash and one char or two dashes and long name). How this option will be interpreted and whether it will have an argument dependes on the action. See below list of actions. ``option.add_argument(name: &str, action: TypedAction, help: &str)`` Add a positional argument ``option.metavar(var: &str)`` A name of the argument in usage messages (for options having argument). ``option.envvar(var: &str)`` A name of the environment variable to get option value from. The value would be parsed with ``FromStr::from_str``, just like an option having ``Store`` action. ``option.required()`` The option or argument is required (it's optional by default). If multiple options or multiple arguments are defined for this reference at least one of them is required. Actions ======= The following actions are available out of the box. They may be used in either ``add_option`` or ``add_argument``: ``Store`` An option has single argument. Stores a value from command-line in a variable. Any type that has the ``FromStr`` and ``Clone`` traits implemented may be used. ``StoreOption`` As ``Store``, but wrap value with ``Some`` for use with ``Option``. For example: let mut x: Option = None; ap.refer(&mut x).add_option(&["-x"], StoreOption, "Set var x"); ``StoreConst(value)`` An option has no arguments. Store a hard-coded ``value`` into variable, when specified. Any type with the ``Clone`` trait implemented may be used. ``PushConst(value)`` An option has no arguments. Push a hard-coded ``value`` into variable, when specified. Any type which has the ``Clone`` type implemented may be used. Option might used for a list of operations to perform, when ``required`` is set for this variable, at least one operation is required. ``StoreTrue`` Stores boolean ``true`` value in a variable. (shortcut for ``StoreConst(true)``) ``StoreFalse`` Stores boolean ``false`` value in a variable. (shortcut for ``StoreConst(false)``) ``IncrBy(num)`` An option has no arguments. Increments the value stored in a variable by a value ``num``. Any type which has the ``Add`` and ``Clone`` traits may be used. ``DecrBy(nym)`` Decrements the value stored in a variable by a value ``num``. Any type which has the ``Add`` and ``Clone`` traits may be used. ``Collect`` When used for an ``--option``, requires single argument. When used for a positional argument consumes all remaining arguments. Parsed options are added to the list. I.e. a ``Collect`` action requires a ``Vec`` variable. Parses arguments using ``FromStr`` trait. ``List`` When used for positional argument, works the same as ``List``. When used as an option, consumes all remaining arguments. Note the usage of ``List`` is strongly discouraged, because of complex rules below. Use ``Collect`` and positional options if possible. But usage of ``List`` action may be useful if you need shell expansion of anything other than last positional argument. Let's learn rules by example. For the next options:: ap.refer(&mut lst1).add_option(&["-X", "--xx"], List, "List1"); ap.refer(&mut lst2).add_argument("yy", List, "List2"); The following command line:: ./run 1 2 3 -X 4 5 6 Will return ``[1, 2, 3]`` in the ``lst1`` and the ``[4,5,6]`` in the ``lst2``. Note that using when using ``=`` or equivalent short option mode, the 'consume all' mode is not enabled. I.e. in the following command-line:: ./run 1 2 -X3 4 --xx=5 6 The ``lst1`` has ``[3, 5]`` and ``lst2`` has ``[1, 2, 4, 6]``. The argument consuming also stops on ``--`` or the next option:: ./run: -X 1 2 3 -- 4 5 6 ./run: -X 1 2 --xx=3 4 5 6 Both of the above parse ``[4, 5, 6]`` as ``lst1`` and the ``[1, 2, 3]`` as the ``lst2``. ``Print(value)`` Print the text and exit (with status ``0``). Useful for ``--version`` option:: ap.add_option(&["-V", "--version"], Print(env!("CARGO_PKG_VERSION").to_string()), "Show version"); argparse-0.2.2/bulk.yaml010064400037200003720000000002751334216370200133640ustar0000000000000000minimum-bulk: v0.4.5 versions: - file: Cargo.toml block-start: ^\[package\] block-end: ^\[.*\] regex: ^version\s*=\s*"(\S+)" - file: README.rst regex: ^\s*argparse\s*=\s*"(\S+)" argparse-0.2.2/examples/greeting.rs010064400037200003720000000013441334216370200155310ustar0000000000000000extern crate argparse; use argparse::{ArgumentParser, StoreTrue, Store, Print}; fn main() { let mut verbose = false; let mut name = "World".to_string(); { let mut ap = ArgumentParser::new(); ap.set_description("Greet somebody."); ap.add_option(&["-V", "--version"], Print(env!("CARGO_PKG_VERSION").to_string()), "Show version"); ap.refer(&mut verbose) .add_option(&["-v", "--verbose"], StoreTrue, "Be verbose"); ap.refer(&mut name) .add_option(&["--name"], Store, "Name for the greeting"); ap.parse_args_or_exit(); } if verbose { println!("name is {}", name); } println!("Hello {}!", name); } argparse-0.2.2/examples/structure.rs010064400037200003720000000015361334216370200157700ustar0000000000000000extern crate argparse; use std::process::exit; use argparse::{ArgumentParser, StoreTrue, Store}; struct Options { verbose: bool, name: String, } fn main() { let mut options = Options { verbose: false, name: "World".to_string(), }; { let mut ap = ArgumentParser::new(); ap.set_description("Greet somebody."); ap.refer(&mut options.verbose) .add_option(&["-v", "--verbose"], StoreTrue, "Be verbose"); ap.refer(&mut options.name) .add_option(&["--name"], Store, "Name for the greeting"); match ap.parse_args() { Ok(()) => {} Err(x) => { exit(x); } } } if options.verbose { println!("name is {}", options.name); } println!("Hello {}!", options.name); } argparse-0.2.2/examples/subcommands.rs010064400037200003720000000046451334216370200162470ustar0000000000000000use std::str::FromStr; use std::io::{stdout, stderr}; extern crate argparse; use argparse::{ArgumentParser, StoreTrue, Store, List}; #[allow(non_camel_case_types)] #[derive(Debug)] enum Command { play, record, } impl FromStr for Command { type Err = (); fn from_str(src: &str) -> Result { return match src { "play" => Ok(Command::play), "record" => Ok(Command::record), _ => Err(()), }; } } fn play_command(verbose: bool, args: Vec) { let mut output = "".to_string(); { let mut ap = ArgumentParser::new(); ap.set_description("Plays a sound"); ap.refer(&mut output) .add_option(&["--output"], Store, r#"Output sink to play to"#); match ap.parse(args, &mut stdout(), &mut stderr()) { Ok(()) => {} Err(x) => { std::process::exit(x); } } } println!("Verbosity: {}, Output: {}", verbose, output); } fn record_command(verbose: bool, args: Vec) { let mut input = "".to_string(); { let mut ap = ArgumentParser::new(); ap.set_description("Records a sound"); ap.refer(&mut input) .add_option(&["--input"], Store, r#"Output source to record from"#); match ap.parse(args, &mut stdout(), &mut stderr()) { Ok(()) => {} Err(x) => { std::process::exit(x); } } } println!("Verbosity: {}, Input: {}", verbose, input); } fn main() { let mut verbose = false; let mut subcommand = Command::play; let mut args = vec!(); { let mut ap = ArgumentParser::new(); ap.set_description("Plays or records sound"); ap.refer(&mut verbose) .add_option(&["-v", "--verbose"], StoreTrue, "Be verbose"); ap.refer(&mut subcommand).required() .add_argument("command", Store, r#"Command to run (either "play" or "record")"#); ap.refer(&mut args) .add_argument("arguments", List, r#"Arguments for command"#); ap.stop_on_first_argument(true); ap.parse_args_or_exit(); } args.insert(0, format!("subcommand {:?}", subcommand)); match subcommand { Command::play => play_command(verbose, args), Command::record => record_command(verbose, args), } } argparse-0.2.2/src/action.rs010064400037200003720000000011251334216370200141500ustar0000000000000000use std::cell::RefCell; use std::rc::Rc; pub enum ParseResult { Parsed, Help, Exit, Error(String), } pub enum Action<'a> { Flag(Box), Single(Box), Push(Box), Many(Box), } pub trait TypedAction { fn bind<'x>(&self, Rc>) -> Action<'x>; } pub trait IFlagAction { fn parse_flag(&self) -> ParseResult; } pub trait IArgAction { fn parse_arg(&self, arg: &str) -> ParseResult; } pub trait IArgsAction { fn parse_args(&self, args: &[&str]) -> ParseResult; } argparse-0.2.2/src/bool.rs010064400037200003720000000011361334216370200136300ustar0000000000000000use std::cell::RefCell; use std::rc::Rc; use super::action::Action; use super::action::TypedAction; use super::action::Action::Flag; use super::generic::StoreConstAction; use super::{StoreTrue, StoreFalse}; impl TypedAction for StoreTrue { fn bind<'x>(&self, cell: Rc>) -> Action<'x> { return Flag(Box::new(StoreConstAction { cell: cell, value: true })); } } impl TypedAction for StoreFalse { fn bind<'x>(&self, cell: Rc>) -> Action<'x> { return Flag(Box::new(StoreConstAction { cell: cell, value: false })); } } argparse-0.2.2/src/custom.rs010064400037200003720000000055061334216370200142140ustar0000000000000000use std::cell::RefCell; use std::rc::Rc; use super::{Parse, ParseOption, ParseList, ParseCollect, FromCommandLine}; use super::action::Action; use super::action::{TypedAction, IArgAction, IArgsAction}; use super::action::ParseResult; use super::action::ParseResult::{Parsed, Error}; use super::action::Action::{Single, Push, Many}; pub struct ParseAction<'a, T: 'a> { pub cell: Rc>, } pub struct ParseOptionAction<'a, T: 'a> { cell: Rc>>, } pub struct ParseListAction<'a, T: 'a> { cell: Rc>>, } impl TypedAction for Parse { fn bind<'x>(&self, cell: Rc>) -> Action<'x> { return Single(Box::new(ParseAction { cell: cell })); } } impl TypedAction> for ParseOption { fn bind<'x>(&self, cell: Rc>>) -> Action<'x> { return Single(Box::new(ParseOptionAction { cell: cell })); } } impl TypedAction> for ParseList { fn bind<'x>(&self, cell: Rc>>) -> Action<'x> { return Many(Box::new(ParseListAction { cell: cell })); } } impl TypedAction> for ParseCollect where T: 'static + FromCommandLine + Clone { fn bind<'x>(&self, cell: Rc>>) -> Action<'x> { return Push(Box::new(ParseListAction { cell: cell })) } } impl<'a, T: FromCommandLine> IArgAction for ParseAction<'a, T> { fn parse_arg(&self, arg: &str) -> ParseResult { match FromCommandLine::from_argument(arg) { Ok(x) => { **self.cell.borrow_mut() = x; return Parsed; } Err(error) => { return Error(format!("Bad value {:?}: {}", arg, error)); } } } } impl<'a, T: FromCommandLine> IArgAction for ParseOptionAction<'a, T> { fn parse_arg(&self, arg: &str) -> ParseResult { match FromCommandLine::from_argument(arg) { Ok(x) => { **self.cell.borrow_mut() = Some(x); return Parsed; } Err(error) => { return Error(format!("Bad value {:?}: {}", arg, error)); } } } } impl<'a, T: FromCommandLine + Clone> IArgsAction for ParseListAction<'a, T> { fn parse_args(&self, args: &[&str]) -> ParseResult { let mut result = vec!(); for arg in args.iter() { match FromCommandLine::from_argument(*arg) { Ok(x) => { result.push(x); } Err(error) => { return Error(format!("Bad value {:?}: {}", arg, error)); } } } **self.cell.borrow_mut() = result; return Parsed; } } argparse-0.2.2/src/from_cli.rs010064400037200003720000000056531334216370200144770ustar0000000000000000use std::str::FromStr; use std::path::PathBuf; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; use super::FromCommandLine; impl FromCommandLine for PathBuf { fn from_argument(s: &str) -> Result { Ok(From::from(s)) } } impl FromCommandLine for f32 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for f64 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } // TODO(tailhook) implement various radices for integer values impl FromCommandLine for isize { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for i8 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for i16 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for i32 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for i64 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for usize { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for u8 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for u16 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for u32 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for u64 { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for bool { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for String { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|_| unreachable!()) } } impl FromCommandLine for Ipv4Addr { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for Ipv6Addr { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } impl FromCommandLine for SocketAddr { fn from_argument(s: &str) -> Result { FromStr::from_str(s).map_err(|e| format!("{:?}", e)) } } argparse-0.2.2/src/generic.rs010064400037200003720000000075101334216370200143130ustar0000000000000000use std::cell::RefCell; use std::str::FromStr; use std::rc::Rc; use super::{StoreConst, Store, StoreOption, List, Collect, PushConst}; use super::action::Action; use super::action::{TypedAction, IFlagAction, IArgAction, IArgsAction}; use super::action::ParseResult; use super::action::ParseResult::{Parsed, Error}; use super::action::Action::{Flag, Single, Push, Many}; pub struct StoreConstAction<'a, T: 'a> { pub value: T, pub cell: Rc>, } pub struct PushConstAction<'a, T: 'a> { pub value: T, pub cell: Rc>>, } pub struct StoreAction<'a, T: 'a> { pub cell: Rc>, } pub struct StoreOptionAction<'a, T: 'a> { cell: Rc>>, } pub struct ListAction<'a, T: 'a> { cell: Rc>>, } impl TypedAction for StoreConst { fn bind<'x>(&self, cell: Rc>) -> Action<'x> { let StoreConst(ref val) = *self; return Flag(Box::new(StoreConstAction { cell: cell, value: val.clone() })); } } impl TypedAction> for PushConst { fn bind<'x>(&self, cell: Rc>>) -> Action<'x> { let PushConst(ref val) = *self; return Flag(Box::new(PushConstAction { cell: cell, value: val.clone() })); } } impl TypedAction for Store { fn bind<'x>(&self, cell: Rc>) -> Action<'x> { return Single(Box::new(StoreAction { cell: cell })); } } impl TypedAction> for StoreOption { fn bind<'x>(&self, cell: Rc>>) -> Action<'x> { return Single(Box::new(StoreOptionAction { cell: cell })); } } impl TypedAction> for List { fn bind<'x>(&self, cell: Rc>>) -> Action<'x> { return Many(Box::new(ListAction { cell: cell })); } } impl TypedAction> for Collect { fn bind<'x>(&self, cell: Rc>>) -> Action<'x> { return Push(Box::new(ListAction { cell: cell })); } } impl<'a, T: Clone> IFlagAction for StoreConstAction<'a, T> { fn parse_flag(&self) -> ParseResult { let mut targ = self.cell.borrow_mut(); **targ = self.value.clone(); return Parsed; } } impl<'a, T: Clone> IFlagAction for PushConstAction<'a, T> { fn parse_flag(&self) -> ParseResult { let mut targ = self.cell.borrow_mut(); targ.push(self.value.clone()); return Parsed; } } impl<'a, T: FromStr> IArgAction for StoreAction<'a, T> { fn parse_arg(&self, arg: &str) -> ParseResult { match FromStr::from_str(arg) { Ok(x) => { **self.cell.borrow_mut() = x; return Parsed; } Err(_) => { return Error(format!("Bad value {}", arg)); } } } } impl<'a, T: FromStr> IArgAction for StoreOptionAction<'a, T> { fn parse_arg(&self, arg: &str) -> ParseResult { match FromStr::from_str(arg) { Ok(x) => { **self.cell.borrow_mut() = Some(x); return Parsed; } Err(_) => { return Error(format!("Bad value {}", arg)); } } } } impl<'a, T: FromStr + Clone> IArgsAction for ListAction<'a, T> { fn parse_args(&self, args: &[&str]) -> ParseResult { let mut result = vec!(); for arg in args.iter() { match FromStr::from_str(*arg) { Ok(x) => { result.push(x); } Err(_) => { return Error(format!("Bad value {}", arg)); } } } **self.cell.borrow_mut() = result; return Parsed; } } argparse-0.2.2/src/help.rs010064400037200003720000000043151334216370200136270ustar0000000000000000use std::str::CharIndices; use std::io::Result as IoResult; use std::io::Write; use super::action::{IFlagAction, ParseResult}; use super::action::ParseResult::Help; pub struct HelpAction; impl IFlagAction for HelpAction { fn parse_flag(&self) -> ParseResult { return Help; } } struct WordsIter<'a> { data: &'a str, iter: CharIndices<'a>, } impl<'a> WordsIter<'a> { fn new(data: &'a str) -> WordsIter<'a> { return WordsIter { data: data, iter: data.char_indices(), }; } } impl<'a> Iterator for WordsIter<'a> { type Item = &'a str; fn next(&mut self) -> Option<&'a str> { let word_start; loop { let (idx, ch) = match self.iter.next() { None => return None, Some((idx, ch)) => ((idx, ch)), }; match ch { ' ' | '\t' | '\r' | '\n' => continue, _ => { word_start = idx; break; } } } loop { let (idx, ch) = match self.iter.next() { None => break, Some((idx, ch)) => ((idx, ch)), }; match ch { ' ' | '\t' | '\r' | '\n' => { return Some(&self.data[word_start..idx]); } _ => continue, } } return Some(&self.data[word_start..self.data.len()]); } } pub fn wrap_text(buf: &mut Write, data: &str, width: usize, indent: usize) -> IoResult<()> { let mut witer = WordsIter::new(data); let mut off = indent; match witer.next() { None => { return Ok(()); } Some(word) => { try!(buf.write(word.as_bytes())); off += word.len(); } } for word in witer { if off + word.len() + 1 > width { try!(buf.write(b"\n")); for _ in 0..indent { try!(buf.write(b" ")); } off = indent; } else { try!(buf.write(b" ")); off += 1; } try!(buf.write(word.as_bytes())); off += word.len(); } return Ok(()); } argparse-0.2.2/src/lib.rs010064400037200003720000000022731334216370200134460ustar0000000000000000#![crate_name = "argparse"] #![crate_type = "lib"] pub use self::parser::{ArgumentParser, Ref}; pub mod action; pub mod parser; mod generic; mod custom; mod help; mod print; mod bool; mod num; mod from_cli; pub trait FromCommandLine: Sized { fn from_argument(s: &str) -> Result; } // TODO(tailhook) make consts pub struct StoreTrue; pub struct StoreFalse; pub struct StoreConst(pub T); pub struct PushConst(pub T); pub struct Store; pub struct Parse; pub struct StoreOption; pub struct ParseOption; pub struct List; pub struct ParseList; pub struct Collect; pub struct ParseCollect; /// Print string and exit with status 0 /// /// Particularly useful for `--version` option and similar pub struct Print(pub String); pub struct IncrBy(pub T); pub struct DecrBy(pub T); #[cfg(test)] mod test_parser; #[cfg(test)] mod test_bool; #[cfg(test)] mod test_int; #[cfg(test)] mod test_float; #[cfg(test)] mod test_str; #[cfg(test)] mod test_enum; #[cfg(test)] mod test_pos; #[cfg(test)] mod test_many; #[cfg(test)] mod test_optional; #[cfg(test)] mod test_usage; #[cfg(test)] mod test_help; #[cfg(test)] mod test_env; #[cfg(test)] mod test_const; #[cfg(test)] mod test_path; argparse-0.2.2/src/num.rs010064400037200003720000000032041334216370200134720ustar0000000000000000use std::cell::RefCell; use std::rc::Rc; use std::ops::{Add, Sub}; use super::{IncrBy, DecrBy}; use super::action::{TypedAction, Action, ParseResult}; use super::action::ParseResult::Parsed; use super::action::IFlagAction; use super::action::Action::Flag; pub struct IncrByAction<'a, T: 'a> { delta: T, cell: Rc>, } pub struct DecrByAction<'a, T: 'a> { delta: T, cell: Rc>, } impl + Clone> TypedAction for IncrBy { fn bind<'x>(&self, cell: Rc>) -> Action<'x> { let IncrBy(ref delta) = *self; return Flag(Box::new(IncrByAction { cell: cell, delta: delta.clone() })); } } impl + Clone> TypedAction for DecrBy { fn bind<'x>(&self, cell: Rc>) -> Action<'x> { let DecrBy(ref delta) = *self; return Flag(Box::new(DecrByAction { cell: cell, delta: delta.clone() })); } } impl<'a, T: Add + Clone> IFlagAction for IncrByAction<'a, T> { fn parse_flag(&self) -> ParseResult { let oldval = { let targ = self.cell.borrow(); targ.clone() }; let mut targ = self.cell.borrow_mut(); **targ = oldval + self.delta.clone(); return Parsed; } } impl<'a, T: Sub + Clone> IFlagAction for DecrByAction<'a, T> { fn parse_flag(&self) -> ParseResult { let oldval = { let targ = self.cell.borrow(); targ.clone() }; let mut targ = self.cell.borrow_mut(); **targ = oldval - self.delta.clone(); return Parsed; } } argparse-0.2.2/src/parser.rs010064400037200003720000000743261334216370200142040ustar0000000000000000use std::env; use std::io::{Write}; use std::io::Result as IoResult; use std::io::{stdout, stderr}; use std::rc::Rc; use std::cell::RefCell; use std::iter::Peekable; use std::slice::Iter; use std::hash::Hash; use std::hash::Hasher; use std::str::FromStr; use std::process::exit; #[allow(unused_imports)] #[allow(deprecated)] use std::ascii::AsciiExt; use std::collections::HashMap; use std::collections::hash_map::Entry; use std::collections::HashSet; use super::action::{Action, ParseResult}; use super::action::ParseResult::{Parsed, Help, Exit, Error}; use super::action::TypedAction; use super::action::Action::{Flag, Single, Push, Many}; use super::action::IArgAction; use super::generic::StoreAction; use super::help::{HelpAction, wrap_text}; use action::IFlagAction; use self::ArgumentKind::{Positional, ShortOption, LongOption, Delimiter}; static OPTION_WIDTH: usize = 24; static TOTAL_WIDTH: usize = 79; enum ArgumentKind { Positional, ShortOption, LongOption, Delimiter, // Barely "--" } impl ArgumentKind { fn check(name: &str) -> ArgumentKind { let mut iter = name.chars(); let char1 = iter.next(); let char2 = iter.next(); let char3 = iter.next(); return match char1 { Some('-') => match char2 { Some('-') => match char3 { Some(_) => LongOption, // --opt None => Delimiter, // just -- }, Some(_) => ShortOption, // -opts None => Positional, // single dash }, Some(_) | None => Positional, } } } struct GenericArgument<'parser> { id: usize, varid: usize, name: &'parser str, help: &'parser str, action: Action<'parser>, } struct GenericOption<'parser> { id: usize, varid: Option, names: Vec<&'parser str>, help: &'parser str, action: Action<'parser>, } struct EnvVar<'parser> { varid: usize, name: &'parser str, action: Box, } impl<'a> Hash for GenericOption<'a> { fn hash(&self, state: &mut H) where H: Hasher { self.id.hash(state); } } impl<'a> PartialEq for GenericOption<'a> { fn eq(&self, other: &GenericOption<'a>) -> bool { return self.id == other.id; } } impl<'a> Eq for GenericOption<'a> {} impl<'a> Hash for GenericArgument<'a> { fn hash(&self, state: &mut H) where H: Hasher { self.id.hash(state); } } impl<'a> PartialEq for GenericArgument<'a> { fn eq(&self, other: &GenericArgument<'a>) -> bool { return self.id == other.id; } } impl<'a> Eq for GenericArgument<'a> {} pub struct Var { id: usize, metavar: String, required: bool, } impl Hash for Var { fn hash(&self, state: &mut H) where H: Hasher { self.id.hash(state); } } impl PartialEq for Var { fn eq(&self, other: &Var) -> bool { return self.id == other.id; } } impl Eq for Var {} struct Context<'ctx, 'parser: 'ctx> { parser: &'ctx ArgumentParser<'parser>, set_vars: HashSet, list_options: HashMap>, Vec<&'ctx str>>, list_arguments: HashMap>, Vec<&'ctx str>>, arguments: Vec<&'ctx str>, iter: Peekable>, stderr: &'ctx mut (Write + 'ctx), } impl<'a, 'b> Context<'a, 'b> { fn parse_option(&mut self, opt: Rc>, optarg: Option<&'a str>) -> ParseResult { let value = match optarg { Some(value) => value, None => match self.iter.next() { Some(value) => { &value[..] } None => { return match opt.action { Many(_) => Parsed, _ => Error(format!( // TODO(tailhook) is {:?} ok? "Option {:?} requires an argument", opt.names)), }; } }, }; match opt.varid { Some(varid) => { self.set_vars.insert(varid); } None => {} } match opt.action { Single(ref action) => { return action.parse_arg(value); } Push(_) => { (match self.list_options.entry(opt.clone()) { Entry::Occupied(occ) => occ.into_mut(), Entry::Vacant(vac) => vac.insert(Vec::new()), }).push(value); return Parsed; } Many(_) => { let vec = match self.list_options.entry(opt.clone()) { Entry::Occupied(occ) => occ.into_mut(), Entry::Vacant(vac) => vac.insert(Vec::new()), }; vec.push(value); match optarg { Some(_) => return Parsed, _ => {} } loop { match self.iter.peek() { None => { break; } Some(arg) if arg.starts_with("-") => { break; } Some(value) => { vec.push(&value[..]); } } self.iter.next(); } return Parsed; } _ => panic!(), }; } fn parse_long_option(&mut self, arg: &'a str) -> ParseResult { let mut equals_iter = arg.splitn(2, '='); let optname = equals_iter.next().unwrap(); let valueref = equals_iter.next(); let opt = self.parser.long_options.get(&optname.to_string()); match opt { Some(opt) => { match opt.action { Flag(ref action) => { match valueref { Some(_) => { return Error(format!( "Option {} does not accept an argument", optname)); } None => { match opt.varid { Some(varid) => { self.set_vars.insert(varid); } None => {} } return action.parse_flag(); } } } Single(_) | Push(_) | Many(_) => { return self.parse_option(opt.clone(), valueref); } } } None => { return Error(format!("Unknown option {}", arg)); } } } fn parse_short_options<'x>(&'x mut self, arg: &'a str) -> ParseResult { let mut iter = arg.char_indices(); iter.next(); for (idx, ch) in iter { let opt = match self.parser.short_options.get(&ch) { Some(opt) => { opt } None => { return Error(format!("Unknown short option \"{}\"", ch)); } }; let res = match opt.action { Flag(ref action) => { match opt.varid { Some(varid) => { self.set_vars.insert(varid); } None => {} } action.parse_flag() } Single(_) | Push(_) | Many(_) => { let value; if idx + 1 < arg.len() { value = Some(&arg[idx+1..arg.len()]); } else { value = None; } return self.parse_option(opt.clone(), value); } }; match res { Parsed => { continue; } x => { return x; } } } return Parsed; } fn postpone_argument(&mut self, arg: &'a str) { self.arguments.push(arg); } fn parse_options(&mut self) -> ParseResult { self.iter.next(); // Command name loop { let next = self.iter.next(); let arg = match next { Some(arg) => { arg } None => { break; } }; let res = match ArgumentKind::check(&arg[..]) { Positional => { self.postpone_argument(&arg[..]); if self.parser.stop_on_first_argument { break; } continue; } LongOption => self.parse_long_option(&arg[..]), ShortOption => self.parse_short_options(&arg[..]), Delimiter => { if !self.parser.silence_double_dash { self.postpone_argument("--"); } break; } }; match res { Parsed => continue, _ => return res, } } loop { match self.iter.next() { None => break, Some(arg) => self.postpone_argument(&arg[..]), } } return Parsed; } fn parse_arguments(&mut self) -> ParseResult { let mut pargs = self.parser.arguments.iter(); for arg in self.arguments.iter() { let opt; loop { match pargs.next() { Some(option) => { if self.set_vars.contains(&option.varid) { continue; } opt = option; break; } None => match self.parser.catchall_argument { Some(ref option) => { opt = option; break; } None => return Error(format!( "Unexpected argument {}", arg)), } }; } let res = match opt.action { Single(ref act) => { self.set_vars.insert(opt.varid); act.parse_arg(*arg) }, Many(_) | Push(_) => { (match self.list_arguments.entry(opt.clone()) { Entry::Occupied(occ) => occ.into_mut(), Entry::Vacant(vac) => vac.insert(Vec::new()), }).push(*arg); Parsed }, _ => unreachable!(), }; match res { Parsed => continue, _ => return res, } } return Parsed; } fn parse_list_vars(&mut self) -> ParseResult { for (opt, lst) in self.list_options.iter() { match opt.action { Push(ref act) | Many(ref act) => { let res = act.parse_args(&lst[..]); match res { Parsed => continue, _ => return res, } } _ => panic!(), } } for (opt, lst) in self.list_arguments.iter() { match opt.action { Push(ref act) | Many(ref act) => { let res = act.parse_args(&lst[..]); match res { Parsed => continue, _ => return res, } } _ => panic!(), } } return Parsed; } fn parse_env_vars(&mut self) -> ParseResult { for evar in self.parser.env_vars.iter() { match env::var(evar.name) { Ok(val) => { match evar.action.parse_arg(&val[..]) { Parsed => { self.set_vars.insert(evar.varid); continue; } Error(err) => { write!(self.stderr, "WARNING: Environment variable {}: {}\n", evar.name, err).ok(); } _ => unreachable!(), } } Err(_) => {} } } return Parsed; } fn check_required(&mut self) -> ParseResult { // Check for required arguments for var in self.parser.vars.iter() { if var.required && !self.set_vars.contains(&var.id) { // First try positional arguments for opt in self.parser.arguments.iter() { if opt.varid == var.id { return Error(format!( "Argument {} is required", opt.name)); } } // Then options let mut all_options = vec!(); for opt in self.parser.options.iter() { match opt.varid { Some(varid) if varid == var.id => {} _ => { continue } } all_options.extend(opt.names.clone().into_iter()); } if all_options.len() > 1 { return Error(format!( "One of the options {:?} is required", all_options)); } else if all_options.len() == 1 { return Error(format!( "Option {:?} is required", all_options)); } // Then envvars for envvar in self.parser.env_vars.iter() { if envvar.varid == var.id { return Error(format!( "Environment var {} is required", envvar.name)); } } } } return Parsed; } fn parse(parser: &ArgumentParser, args: &Vec, stderr: &mut Write) -> ParseResult { let mut ctx = Context { parser: parser, iter: args.iter().peekable(), set_vars: HashSet::new(), list_options: HashMap::new(), list_arguments: HashMap::new(), arguments: Vec::new(), stderr: stderr, }; match ctx.parse_env_vars() { Parsed => {} x => { return x; } } match ctx.parse_options() { Parsed => {} x => { return x; } } match ctx.parse_arguments() { Parsed => {} x => { return x; } } match ctx.parse_list_vars() { Parsed => {} x => { return x; } } match ctx.check_required() { Parsed => {} x => { return x; } } return Parsed; } } pub struct Ref<'parser:'refer, 'refer, T: 'parser> { cell: Rc>, varid: usize, parser: &'refer mut ArgumentParser<'parser>, } impl<'parser, 'refer, T> Ref<'parser, 'refer, T> { pub fn add_option<'x, A: TypedAction>(&'x mut self, names: &[&'parser str], action: A, help: &'parser str) -> &'x mut Ref<'parser, 'refer, T> { { let var = &mut self.parser.vars[self.varid]; if var.metavar.len() == 0 { let mut longest_name = names[0]; let mut llen = longest_name.len(); for name in names.iter() { if name.len() > llen { longest_name = *name; llen = longest_name.len(); } } if llen > 2 { var.metavar = longest_name[2..llen] .to_ascii_uppercase().replace("-", "_"); } } } self.parser.add_option_for(Some(self.varid), names, action.bind(self.cell.clone()), help); return self; } pub fn add_argument<'x, A: TypedAction>(&'x mut self, name: &'parser str, action: A, help: &'parser str) -> &'x mut Ref<'parser, 'refer, T> { let act = action.bind(self.cell.clone()); let opt = Rc::new(GenericArgument { id: self.parser.arguments.len(), varid: self.varid, name: name, help: help, action: act, }); match opt.action { Flag(_) => panic!("Flag arguments can't be positional"), Many(_) | Push(_) => { match self.parser.catchall_argument { Some(ref y) => panic!(format!( "Option {} conflicts with option {}", name, y.name)), None => {}, } self.parser.catchall_argument = Some(opt); } Single(_) => { self.parser.arguments.push(opt); } } { let var = &mut self.parser.vars[self.varid]; if var.metavar.len() == 0 { var.metavar = name.to_string(); } } return self; } pub fn metavar<'x>(&'x mut self, name: &str) -> &'x mut Ref<'parser, 'refer, T> { { let var = &mut self.parser.vars[self.varid]; var.metavar = name.to_string(); } return self; } pub fn required<'x>(&'x mut self) -> &'x mut Ref<'parser, 'refer, T> { { let var = &mut self.parser.vars[self.varid]; var.required = true; } return self; } } impl<'parser, 'refer, T: 'static + FromStr> Ref<'parser, 'refer, T> { pub fn envvar<'x>(&'x mut self, varname: &'parser str) -> &'x mut Ref<'parser, 'refer, T> { self.parser.env_vars.push(Rc::new(EnvVar { varid: self.varid, name: varname, action: Box::new(StoreAction { cell: self.cell.clone() }), })); return self; } } /// The main argument parser class pub struct ArgumentParser<'parser> { description: &'parser str, vars: Vec>, options: Vec>>, arguments: Vec>>, env_vars: Vec>>, catchall_argument: Option>>, short_options: HashMap>>, long_options: HashMap>>, stop_on_first_argument: bool, silence_double_dash: bool, } impl<'parser> ArgumentParser<'parser> { /// Create an empty argument parser pub fn new() -> ArgumentParser<'parser> { let mut ap = ArgumentParser { description: "", vars: Vec::new(), env_vars: Vec::new(), arguments: Vec::new(), catchall_argument: None, options: Vec::new(), short_options: HashMap::new(), long_options: HashMap::new(), stop_on_first_argument: false, silence_double_dash: true, }; ap.add_option_for(None, &["-h", "--help"], Flag(Box::new(HelpAction)), "Show this help message and exit"); return ap; } /// Borrow mutable variable for an argument /// /// This returns `Ref` object which should be used configure the option pub fn refer<'x, T>(&'x mut self, val: &'parser mut T) -> Box> { let cell = Rc::new(RefCell::new(val)); let id = self.vars.len(); self.vars.push(Box::new(Var { id: id, required: false, metavar: "".to_string(), })); return Box::new(Ref { cell: cell.clone(), varid: id, parser: self, }); } /// Add option to argument parser /// /// This is only useful for options that don't store value. For /// example `Print(...)` pub fn add_option(&mut self, names: &[&'parser str], action: F, help: &'parser str) { self.add_option_for(None, names, Flag(Box::new(action)), help); } /// Set description of the command pub fn set_description(&mut self, descr: &'parser str) { self.description = descr; } fn add_option_for(&mut self, var: Option, names: &[&'parser str], action: Action<'parser>, help: &'parser str) { let opt = Rc::new(GenericOption { id: self.options.len(), varid: var, names: names.to_vec(), help: help, action: action, }); if names.len() < 1 { panic!("At least one name for option must be specified"); } for nameptr in names.iter() { let name = *nameptr; match ArgumentKind::check(name) { Positional|Delimiter => { panic!("Bad argument name {}", name); } LongOption => { self.long_options.insert( name.to_string(), opt.clone()); } ShortOption => { if name.len() > 2 { panic!("Bad short argument {}", name); } self.short_options.insert( name.as_bytes()[1] as char, opt.clone()); } } } self.options.push(opt); } /// Print help /// /// Usually command-line option is used for printing help, /// this is here for any awkward cases pub fn print_help(&self, name: &str, writer: &mut Write) -> IoResult<()> { return HelpFormatter::print_help(self, name, writer); } /// Print usage /// /// Usually printed into stderr on error of command-line parsing pub fn print_usage(&self, name: &str, writer: &mut Write) -> IoResult<()> { return HelpFormatter::print_usage(self, name, writer); } /// Parse arguments /// /// This is most powerful method. Usually you need `parse_args` /// or `parse_args_or_exit` instead pub fn parse(&self, args: Vec, stdout: &mut Write, stderr: &mut Write) -> Result<(), i32> { let name = if args.len() > 0 { &args[0][..] } else { "unknown" }; match Context::parse(self, &args, stderr) { Parsed => return Ok(()), Exit => return Err(0), Help => { self.print_help(name, stdout).unwrap(); return Err(0); } Error(message) => { self.error(&name[..], &message[..], stderr); return Err(2); } } } /// Write an error similar to one produced by the library itself /// /// Only needed if you like to do some argument validation that is out /// of scope of the argparse pub fn error(&self, command: &str, message: &str, writer: &mut Write) { self.print_usage(command, writer).unwrap(); write!(writer, "{}: {}\n", command, message).ok(); } /// Configure parser to ignore options when first non-option argument is /// encountered. /// /// Useful for commands that want to pass following options to the /// subcommand or subprocess, but need some options to be set before /// command is specified. pub fn stop_on_first_argument(&mut self, want_stop: bool) { self.stop_on_first_argument = want_stop; } /// Do not put double-dash (bare `--`) into argument /// /// The double-dash is used to stop parsing options and treat all the /// following tokens as the arguments regardless of whether they start /// with dash (minus) or not. /// /// The method only useful for `List` arguments. On by default. The method /// allows to set option to `false` so that `cmd xx -- yy` will get /// ``xx -- yy`` as arguments instead of ``xx yy`` by default. This is /// useful if your ``--`` argument is meaningful. Only first double-dash /// is ignored by default. pub fn silence_double_dash(&mut self, silence: bool) { self.silence_double_dash = silence; } /// Convenience method to parse arguments /// /// On error returns error code that is supposed to be returned by /// an application. (i.e. zero on `--help` and `2` on argument error) pub fn parse_args(&self) -> Result<(), i32> { // TODO(tailhook) can we get rid of collect? return self.parse(env::args().collect(), &mut stdout(), &mut stderr()); } /// The simplest conveninece method /// /// The method returns only in case of successful parsing or exits with /// appropriate code (including successful on `--help`) otherwise. pub fn parse_args_or_exit(&self) { // TODO(tailhook) can we get rid of collect? self.parse(env::args().collect(), &mut stdout(), &mut stderr()) .map_err(|c| exit(c)) .ok(); } } struct HelpFormatter<'a, 'b: 'a> { name: &'a str, parser: &'a ArgumentParser<'b>, buf: &'a mut (Write + 'a), } impl<'a, 'b> HelpFormatter<'a, 'b> { pub fn print_usage(parser: &ArgumentParser, name: &str, writer: &mut Write) -> IoResult<()> { return HelpFormatter { parser: parser, name: name, buf: writer } .write_usage(); } pub fn print_help(parser: &ArgumentParser, name: &str, writer: &mut Write) -> IoResult<()> { return HelpFormatter { parser: parser, name: name, buf: writer } .write_help(); } pub fn print_argument(&mut self, arg: &GenericArgument<'b>) -> IoResult<()> { let mut num = 2; try!(write!(self.buf, " {}", arg.name)); num += arg.name.len(); if num >= OPTION_WIDTH { try!(write!(self.buf, "\n")); for _ in 0..OPTION_WIDTH { try!(write!(self.buf, " ")); } } else { for _ in num..OPTION_WIDTH { try!(write!(self.buf, " ")); } } try!(wrap_text(self.buf, arg.help, TOTAL_WIDTH, OPTION_WIDTH)); try!(write!(self.buf, "\n")); return Ok(()); } pub fn print_option(&mut self, opt: &GenericOption<'b>) -> IoResult<()> { let mut num = 2; try!(write!(self.buf, " ")); let mut niter = opt.names.iter(); let name = niter.next().unwrap(); try!(write!(self.buf, "{}", name)); num += name.len(); for name in niter { try!(write!(self.buf, ",")); try!(write!(self.buf, "{}", name)); num += name.len() + 1; } match opt.action { Flag(_) => {} Single(_) | Push(_) | Many(_) => { try!(write!(self.buf, " ")); let var = &self.parser.vars[opt.varid.unwrap()]; try!(write!(self.buf, "{}", &var.metavar[..])); num += var.metavar.len() + 1; } } if num >= OPTION_WIDTH { try!(write!(self.buf, "\n")); for _ in 0..OPTION_WIDTH { try!(write!(self.buf, " ")); } } else { for _ in num..OPTION_WIDTH { try!(write!(self.buf, " ")); } } try!(wrap_text(self.buf, opt.help, TOTAL_WIDTH, OPTION_WIDTH)); try!(write!(self.buf, "\n")); return Ok(()); } fn write_help(&mut self) -> IoResult<()> { try!(self.write_usage()); try!(write!(self.buf, "\n")); if self.parser.description.len() > 0 { try!(wrap_text(self.buf, self.parser.description,TOTAL_WIDTH, 0)); try!(write!(self.buf, "\n")); } if self.parser.arguments.len() > 0 || self.parser.catchall_argument.is_some() { try!(write!(self.buf, "\nPositional arguments:\n")); for arg in self.parser.arguments.iter() { try!(self.print_argument(&**arg)); } match self.parser.catchall_argument { Some(ref opt) => { try!(self.print_argument(&**opt)); } None => {} } } if self.parser.short_options.len() > 0 || self.parser.long_options.len() > 0 { try!(write!(self.buf, "\nOptional arguments:\n")); for opt in self.parser.options.iter() { try!(self.print_option(&**opt)); } } return Ok(()); } fn write_usage(&mut self) -> IoResult<()> { try!(write!(self.buf, "Usage:\n ")); try!(write!(self.buf, "{}", self.name)); if self.parser.options.len() != 0 { if self.parser.short_options.len() > 1 || self.parser.long_options.len() > 1 { try!(write!(self.buf, " [OPTIONS]")); } for opt in self.parser.arguments.iter() { let var = &self.parser.vars[opt.varid]; try!(write!(self.buf, " ")); if !var.required { try!(write!(self.buf, "[")); } try!(write!(self.buf, "{}", &opt.name.to_ascii_uppercase()[..])); if !var.required { try!(write!(self.buf, "]")); } } match self.parser.catchall_argument { Some(ref opt) => { let var = &self.parser.vars[opt.varid]; try!(write!(self.buf, " ")); if !var.required { try!(write!(self.buf, "[")); } try!(write!(self.buf, "{}", &opt.name.to_ascii_uppercase()[..])); if !var.required { try!(write!(self.buf, " ...]")); } else { try!(write!(self.buf, " [...]")); } } None => {} } } try!(write!(self.buf, "\n")); return Ok(()); } } argparse-0.2.2/src/print.rs010064400037200003720000000004521334216370200140310ustar0000000000000000use Print; use action::{IFlagAction, ParseResult}; impl IFlagAction for Print { fn parse_flag(&self) -> ParseResult { if self.0.ends_with("\n") { print!("{}", self.0); } else { println!("{}", self.0); } return ParseResult::Exit; } } argparse-0.2.2/src/test_bool.rs010064400037200003720000000047741334216370200147020ustar0000000000000000use parser::ArgumentParser; use super::Store; use super::{StoreTrue, StoreFalse}; use test_parser::{check_ok}; fn store_true(args: &[&str]) -> bool { let mut verbose = false; { let mut ap = ArgumentParser::new(); ap.refer(&mut verbose) .add_option(&["-t", "--true"], StoreTrue, "Store true action"); check_ok(&ap, args); } return verbose; } #[test] fn test_store_true() { assert!(!store_true(&["./argparse_test"])); assert!(store_true(&["./argparse_test", "--true"])); } fn store_false(args: &[&str]) -> bool { let mut verbose = true; { let mut ap = ArgumentParser::new(); ap.refer(&mut verbose) .add_option(&["-f", "--false"], StoreFalse, "Store false action"); check_ok(&ap, args); } return verbose; } #[test] fn test_store_false() { assert!(store_false(&["./argparse_test"])); assert!(!store_false(&["./argparse_test", "--false"])); } fn store_bool(args: &[&str]) -> bool { let mut verbose = false; { let mut ap = ArgumentParser::new(); ap.refer(&mut verbose) .add_option(&["-f", "--false"], StoreFalse, "Store false action") .add_option(&["-t", "--true"], StoreTrue, "Store false action"); check_ok(&ap, args); } return verbose; } #[test] fn test_bool() { assert!(!store_bool(&["./argparse_test"])); assert!(store_bool(&["./argparse_test", "-t"])); assert!(!store_bool(&["./argparse_test", "-f"])); assert!(store_bool(&["./argparse_test", "-fft"])); assert!(!store_bool(&["./argparse_test", "-fffft", "-f"])); assert!(store_bool(&["./argparse_test", "--false", "-fffft", "-f", "--true"])); } fn set_bool(args: &[&str]) -> bool { let mut verbose = false; { let mut ap = ArgumentParser::new(); ap.refer(&mut verbose) .add_option(&["-s", "--set"], Store, "Set boolean value"); check_ok(&ap, args); } return verbose; } #[test] fn test_set_bool() { assert!(!set_bool(&["./argparse_test"])); assert!(set_bool(&["./argparse_test", "-strue"])); assert!(!set_bool(&["./argparse_test", "-sfalse"])); // Unfortunately other values do not work } #[test] #[should_panic(expected="Bad value yes")] fn test_bad_bools1() { assert!(!set_bool(&["./argparse_test", "-syes"])); } #[test] #[should_panic(expected="Bad value no")] fn test_bad_bools2() { assert!(!set_bool(&["./argparse_test", "-sno"])); } argparse-0.2.2/src/test_const.rs010064400037200003720000000015271334216370200150660ustar0000000000000000use parser::ArgumentParser; use super::{PushConst}; use test_parser::{check_ok}; fn push_const(args: &[&str]) -> Vec { let mut res = vec!(); { let mut ap = ArgumentParser::new(); ap.refer(&mut res) .add_option(&["-o", "--one"], PushConst(1), "Add one to the list") .add_option(&["-t", "--two"], PushConst(2), "Add two to the list") .add_option(&["-3", "--three"], PushConst(3), "Add three to the list"); check_ok(&ap, args); } return res; } #[test] fn test_push() { assert_eq!(push_const(&["./argparse_test"]), vec!()); assert_eq!(push_const(&["./argparse_test", "--one"]), vec!(1)); assert_eq!(push_const(&["./argparse_test", "-3"]), vec!(3)); assert_eq!(push_const(&["./argparse_test", "-oo3tt"]), vec!(1, 1, 3, 2, 2)); } argparse-0.2.2/src/test_enum.rs010064400037200003720000000020431334216370200146760ustar0000000000000000use std::str::FromStr; use parser::ArgumentParser; use super::Store; use test_parser::{check_ok}; use self::Greeting::{Hello, Hi, NoGreeting}; #[derive(PartialEq, Eq, Debug)] enum Greeting { Hello, Hi, NoGreeting, } impl FromStr for Greeting { type Err = (); fn from_str(src: &str) -> Result { return match src { "hello" => Ok(Hello), "hi" => Ok(Hi), _ => Err(()), }; } } fn parse_enum(args: &[&str]) -> Greeting { let mut val = NoGreeting; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-g"], Store, "Greeting"); check_ok(&ap, args); } return val; } #[test] fn test_parse_enum() { assert_eq!(parse_enum(&["./argparse_test"]), NoGreeting); assert_eq!(parse_enum(&["./argparse_test", "-ghello"]), Hello); assert_eq!(parse_enum(&["./argparse_test", "-ghi"]), Hi); } #[test] #[should_panic] fn test_parse_error() { parse_enum(&["./argparse_test", "-ghell"]); } argparse-0.2.2/src/test_env.rs010064400037200003720000000024101334216370200145200ustar0000000000000000use std::env; use parser::ArgumentParser; use super::Store; use test_parser::{check_ok}; fn required(args: &[&str]) -> (isize, isize) { let mut val1 = 1isize; let mut val2 = 2isize; { let mut ap = ArgumentParser::new(); ap.refer(&mut val1) .add_option(&["--v1"], Store, "The value 1") .add_argument("v1", Store, "The value 1") .envvar("TEST_ENV_REQUIRED_V1") .required(); ap.refer(&mut val2) .add_argument("v2", Store, "The value 2"); check_ok(&ap, args); } return (val1, val2) } #[test] #[should_panic] fn test_required() { env::set_var("TEST_ENV_REQUIRED_V1", "some_crap"); required(&["./argparse_test"]); env::remove_var("TEST_ENV_REQUIRED_V1"); } #[test] fn test_req() { env::set_var("TEST_ENV_REQUIRED_V1", "some_crap"); assert_eq!(required(&["./argparse_test", "10"]), (10, 2)); assert_eq!(required(&["./argparse_test", "11", "21"]), (11, 21)); assert_eq!(required(&["./argparse_test", "--v1=7"]), (7, 2)); env::set_var("TEST_ENV_REQUIRED_V1", "9"); assert_eq!(required(&["./argparse_test", "10"]), (9, 10)); assert_eq!(required(&["./argparse_test", "7", "--v1=15"]), (15, 7)); env::remove_var("TEST_ENV_REQUIRED_V1"); } argparse-0.2.2/src/test_float.rs010064400037200003720000000023251334216370200150420ustar0000000000000000use parser::ArgumentParser; use super::{IncrBy,DecrBy}; use super::Store; use test_parser::{check_ok}; fn incr_decr(args: &[&str]) -> f32 { let mut val = 0f32; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-d", "--decr"], DecrBy(0.25f32), "Decrement value") .add_option(&["-i", "--incr"], IncrBy(0.5f32), "Increment value"); check_ok(&ap, args); } return val; } #[test] fn test_incr_decr() { assert_eq!(incr_decr(&["./argparse_test", "--incr", "-iii"]), 2.0); assert_eq!(incr_decr(&["./argparse_test", "-iiddd", "--incr", "-iii"]), 2.25); } #[test] fn test_float() { let mut val = 0.1; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-s", "--set"], Store, "Set float value"); check_ok(&ap, &["./argparse_test", "-s", "15.125"]); } assert_eq!(val, 15.125); } #[test] #[should_panic] fn test_fail() { let mut val = 0.1; let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-s", "--set"], Store, "Set float value"); check_ok(&ap, &["./argparse_test", "-s", "test"]); } argparse-0.2.2/src/test_help.rs010064400037200003720000000116241334216370200146670ustar0000000000000000use std::str::from_utf8; use parser::ArgumentParser; use super::{Store, List}; #[test] fn test_empty() { let mut ap = ArgumentParser::new(); let mut buf = Vec::::new(); ap.set_description("Test program"); assert!(ap.print_help("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n".to_string() + " ./argparse_test\n" + "\n" + "Test program\n" + "\n" + "Optional arguments:\n" + " -h,--help Show this help message and exit\n" , from_utf8(&buf[..]).unwrap().to_string()); } #[test] fn test_options() { let mut val = 0; let mut val2 = 0; let mut ap = ArgumentParser::new(); ap.set_description("Test program. The description of the program is ought to be very long, because we want to test how word wrapping works for it. So some more text would be ok for the test"); ap.refer(&mut val) .add_option(&["--value"], Store, "Set integer value"); ap.refer(&mut val2) .add_option(&["-L", "--long-option"], Store, "Long option value"); let mut buf = Vec::::new(); assert!(ap.print_help("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n".to_string() + " ./argparse_test [OPTIONS] Test program. The description of the program is ought to be very long, because we want to test how word wrapping works for it. So some more text would be ok for the test\n" + "\n" + "Optional arguments:\n" + " -h,--help Show this help message and exit\n" + " --value VALUE Set integer value\n" + " -L,--long-option LONG_OPTION\n" + " Long option value\n" , from_utf8(&buf[..]).unwrap().to_string()); } #[test] fn test_argument() { let mut val = 0; let mut ap = ArgumentParser::new(); ap.set_description("Test program"); ap.refer(&mut val) .add_argument("value", Store, "Integer value"); let mut buf = Vec::::new(); assert!(ap.print_help("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n".to_string() + " ./argparse_test [VALUE]\n" + "\n" + "Test program\n" + "\n" + "Positional arguments:\n" + " value Integer value\n" + "\n" + "Optional arguments:\n" + " -h,--help Show this help message and exit\n" , from_utf8(&buf[..]).unwrap().to_string()); } #[test] fn test_arguments() { let mut v1 = 0; let mut v2 = Vec::::new(); let mut ap = ArgumentParser::new(); ap.set_description("Test program"); ap.refer(&mut v1) .add_argument("v1", Store, "Integer value 1"); ap.refer(&mut v2) .add_argument("v2", List, "More values"); let mut buf = Vec::::new(); assert!(ap.print_help("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n".to_string() + " ./argparse_test [V1] [V2 ...]\n" + "\n" + "Test program\n" + "\n" + "Positional arguments:\n" + " v1 Integer value 1\n" + " v2 More values\n" + "\n" + "Optional arguments:\n" + " -h,--help Show this help message and exit\n" , from_utf8(&buf[..]).unwrap().to_string()); } #[test] fn test_req_arguments() { let mut v1 = 0; let mut v2 = Vec::::new(); let mut ap = ArgumentParser::new(); ap.set_description("Test program"); ap.refer(&mut v1) .add_argument("v1", Store, "Integer value 1") .required(); ap.refer(&mut v2) .add_argument("v2", List, "More values") .required(); let mut buf = Vec::::new(); assert!(ap.print_help("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n".to_string() + " ./argparse_test V1 V2 [...]\n" + "\n" + "Test program\n" + "\n" + "Positional arguments:\n" + " v1 Integer value 1\n" + " v2 More values\n" + "\n" + "Optional arguments:\n" + " -h,--help Show this help message and exit\n" , from_utf8(&buf[..]).unwrap().to_string()); } #[test] fn test_metavar() { let mut val2 = 0; let mut ap = ArgumentParser::new(); ap.set_description("Test program."); ap.refer(&mut val2) .add_option(&["-L", "--long-option"], Store, "Long option value") .metavar("VAL"); let mut buf = Vec::::new(); assert!(ap.print_help("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n".to_string() + " ./argparse_test [OPTIONS]\n" + "\n" + "Test program.\n" + "\n" + "Optional arguments:\n" + " -h,--help Show this help message and exit\n" + " -L,--long-option VAL Long option value\n" , from_utf8(&buf[..]).unwrap().to_string()); } argparse-0.2.2/src/test_int.rs010064400037200003720000000051701334216370200145300ustar0000000000000000use parser::ArgumentParser; use super::{IncrBy,DecrBy}; use super::Store; use test_parser::{check_ok}; fn incr_int(args: &[&str]) -> usize { let mut val = 0; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-i", "--incr"], IncrBy(1usize), "Increment value"); check_ok(&ap, args); } return val; } #[test] fn test_incr_int() { assert_eq!(incr_int(&["./argparse_test"]), 0); assert_eq!(incr_int(&["./argparse_test", "--incr"]), 1); assert_eq!(incr_int(&["./argparse_test", "-iiiii"]), 5); } fn decr_int(args: &[&str]) -> isize { let mut val = 5; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-d", "--decr"], DecrBy(1isize), "Decrement value"); check_ok(&ap, args); } return val; } #[test] fn test_decr_int() { assert_eq!(decr_int(&["./argparse_test"]), 5); assert_eq!(decr_int(&["./argparse_test", "--decr"]), 4); assert_eq!(decr_int(&["./argparse_test", "-dddddd"]), -1); } #[test] fn test_incr_decr() { let mut val = 0; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-d", "--decr"], DecrBy(1isize), "Decrement value") .add_option(&["-i", "--incr"], IncrBy(1isize), "Increment value"); check_ok(&ap, &["./argparse_test", "-iiddd", "--incr", "-iii"]); } assert_eq!(val, 3); } fn set_int(args: &[&str]) -> isize { let mut val = 0; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-s", "--set"], Store, "Set integer value"); check_ok(&ap, args); } return val; } #[test] fn test_set_int() { assert_eq!(set_int(&["./argparse_test", "-s", "10"]), 10); assert_eq!(set_int(&["./argparse_test", "--set", "99"]), 99); assert_eq!(set_int(&["./argparse_test", "-s", "7", "-s77"]), 77); assert_eq!(set_int(&["./argparse_test", "-s333", "--set=123"]), 123); } #[test] #[should_panic(expected="Bad value 1.5")] fn test_set_int_bad() { set_int(&["./argparse_test", "-s1.5"]); } fn set_i16(args: &[&str]) -> i16 { let mut val = 0; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-s", "--set"], Store, "Set integer value"); check_ok(&ap, args); } return val; } #[test] fn test_i16() { assert_eq!(set_i16(&["./argparse_test", "-s", "124"]), 124); } #[test] #[should_panic(expected="Bad value 1000000")] fn test_i16_big() { set_i16(&["./argparse_test", "-s", "1000000"]); } argparse-0.2.2/src/test_many.rs010064400037200003720000000051641334216370200147050ustar0000000000000000use parser::ArgumentParser; use super::{List, Store, Collect}; use test_parser::{check_ok}; fn pos_list(args: &[&str]) -> (isize, Vec) { let mut val1 = 1; let mut val2 = Vec::new(); { let mut ap = ArgumentParser::new(); ap.refer(&mut val1).add_argument("v1", Store, "The value 1"); ap.refer(&mut val2).add_argument("v2", List, "The list of vals"); check_ok(&ap, args); } return (val1, val2); } #[test] fn test_pos_list() { assert_eq!(pos_list(&["./argparse_test", "10"]), (10, vec!())); assert_eq!(pos_list(&["./argparse_test", "11", "21"]), (11, vec!(21))); assert_eq!(pos_list(&["./argparse_test", "10", "20", "30"]), (10, vec!(20, 30))); } fn pos_collect(args: &[&str]) -> Vec { let mut lst = Vec::new(); { let mut ap = ArgumentParser::new(); ap.refer(&mut lst) .add_argument("v", Collect, "The list of vals"); check_ok(&ap, args); } return lst; } #[test] fn test_pos_collect() { assert_eq!(pos_collect(&["./argparse_test", "10"]), vec!(10)); assert_eq!(pos_collect(&["./argparse_test", "11", "21"]), vec!(11, 21)); assert_eq!(pos_collect(&["./argparse_test", "10", "20", "30"]), vec!(10, 20, 30)); } #[test] #[should_panic] fn wrong_type() { pos_collect(&["./argparse_test", "10", "20", "test"]); } fn collect(args: &[&str]) -> Vec { let mut lst = Vec::new(); { let mut ap = ArgumentParser::new(); ap.refer(&mut lst).add_option(&["-a", "--add"], Collect, "The list of vals"); check_ok(&ap, args); } return lst; } #[test] fn test_collect() { assert_eq!(collect(&["./argparse_test", "-a10"]), vec!(10)); assert_eq!(collect(&["./argparse_test", "--add=11", "-a", "21"]), vec!(11, 21)); assert_eq!(collect(&["./argparse_test", "-a", "10", "--add=20", "--add", "30"]), vec!(10, 20, 30)); } #[test] #[should_panic] fn test_extra() { collect(&["./argparse_test", "-a", "10", "20", "30"]); } fn list(args: &[&str]) -> Vec { let mut vec = Vec::new(); { let mut ap = ArgumentParser::new(); ap.refer(&mut vec).add_option(&["-a", "--add"], List, "The list of vals"); check_ok(&ap, args); } return vec; } #[test] #[should_panic] fn test_list() { assert_eq!(list(&["./argparse_test", "-a10"]), vec!(10)); assert_eq!(list(&["./argparse_test", "--add", "11", "21"]), vec!(11, 21)); assert_eq!(list(&["./argparse_test", "-a", "10", "20", "30"]), vec!(10, 20, 30)); assert_eq!(list(&["./argparse_test", "10", "20", "30"]), vec!(10, 20, 30)); } argparse-0.2.2/src/test_optional.rs010064400037200003720000000024101334216370200155550ustar0000000000000000use parser::ArgumentParser; use super::StoreOption; use test_parser::{check_ok}; fn opt(args: &[&str]) -> Option { let mut val = None; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-s", "--set"], StoreOption, "Set int value"); check_ok(&ap, args); } return val; } #[test] fn test_opt() { assert_eq!(opt(&["./argparse_test"]), None); assert_eq!(opt(&["./argparse_test", "-s", "10"]), Some(10)); assert_eq!(opt(&["./argparse_test", "--set", "11"]), Some(11)); } #[test] #[should_panic] fn test_opt_no_arg() { opt(&["./argparse_test", "--set"]); } fn optstr(args: &[&str]) -> Option { let mut val = None; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-s", "--set"], StoreOption, "Set string value"); check_ok(&ap, args); } return val; } #[test] fn test_str() { assert_eq!(optstr(&["./argparse_test"]), None); assert_eq!(optstr(&["./argparse_test", "-s", "10"]), Some(10.to_string())); assert_eq!(optstr(&["./argparse_test", "--set", "11"]), Some(11.to_string())); } #[test] #[should_panic] fn test_str_no_art() { optstr(&["./argparse_test", "--set"]); } argparse-0.2.2/src/test_parser.rs010064400037200003720000000036201334216370200152300ustar0000000000000000 use parser::ArgumentParser; pub fn check_ok(ap: &ArgumentParser, args: &[&str]) { let mut stdout = Vec::::new(); let mut stderr = Vec::::new(); let mut owned_args = Vec::new(); for x in args.iter() { owned_args.push(x.to_string()); } let res = ap.parse(owned_args, &mut stdout, &mut stderr); match res { Ok(()) => return, Err(x) => panic!( String::from_utf8(stderr).unwrap() + &format!("Expected ok, but found Exit({})", x)[..]), } } pub fn check_exit(ap: &ArgumentParser, args: &[&str]) { let mut stdout = Vec::::new(); let mut stderr = Vec::::new(); let mut owned_args = Vec::new(); for x in args.iter() { owned_args.push(x.to_string()); } let res = ap.parse(owned_args, &mut stdout, &mut stderr); match res { Err(0) => return, Err(x) => panic!(format!("Expected code {} got {}", 0usize, x)), Ok(()) => panic!(format!("Expected failure, got success")), } } pub fn check_err(ap: &ArgumentParser, args: &[&str]) { let mut stdout = Vec::::new(); let mut stderr = Vec::::new(); let mut owned_args = Vec::new(); for x in args.iter() { owned_args.push(x.to_string()); } let res = ap.parse(owned_args, &mut stdout, &mut stderr); match res { Err(2) => return, Err(x) => panic!(format!("Expected code {} got {}", 2usize, x)), Ok(()) => panic!(format!("Expected failure, got success")), } } #[test] fn test_no_arg() { let ap = ArgumentParser::new(); check_ok(&ap, &["./argparse_test"]); check_err(&ap, &["./argparse_test", "a"]); check_err(&ap, &["./argparse_test", "-a"]); check_err(&ap, &["./argparse_test", "--an-option"]); } #[test] fn test_help() { let ap = ArgumentParser::new(); check_ok(&ap, &["./argparse_test"]); check_exit(&ap, &["./argparse_test", "--help"]); } argparse-0.2.2/src/test_path.rs010064400037200003720000000013301334216370200146640ustar0000000000000000use std::path::PathBuf; use parser::ArgumentParser; use super::Parse; use test_parser::{check_ok}; fn parse_str(args: &[&str]) -> PathBuf { let mut val: PathBuf = From::from(""); { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-s", "--set"], Parse, "Set path value"); check_ok(&ap, args); } return val; } #[test] fn test_path() { assert_eq!(parse_str(&["./argparse_test", "-s", "/hello"]), PathBuf::from("/hello")); assert_eq!(parse_str(&["./argparse_test", "--set", "a///b/../c"]), PathBuf::from("a/b/../c")); } #[test] #[should_panic] fn test_err() { parse_str(&["./argparse_test", "--set"]); } argparse-0.2.2/src/test_pos.rs010064400037200003720000000117211334216370200145360ustar0000000000000000use parser::ArgumentParser; use super::{Store, List}; use test_parser::{check_ok}; fn parse_pos(args: &[&str]) -> isize { let mut val = 0; { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_argument("value", Store, "The value"); check_ok(&ap, args); } return val; } #[test] fn test_argument() { assert_eq!(parse_pos(&["./argparse_test", "10"]), 10); } #[test] #[should_panic] fn too_much_args() { parse_pos(&["./argparse_test", "10", "20"]); } #[test] #[should_panic] fn wrong_value() { parse_pos(&["./argparse_test", "test", "20"]); } #[test] #[should_panic] fn float_value() { parse_pos(&["./argparse_test", "1.5"]); } fn parse_two(args: &[&str]) -> (isize, isize) { let mut val1 = 1; let mut val2 = 2; { let mut ap = ArgumentParser::new(); ap.refer(&mut val1) .add_argument("v1", Store, "The value 1"); ap.refer(&mut val2) .add_argument("v2", Store, "The value 2"); check_ok(&ap, args); } return (val1, val2); } #[test] fn test_two() { assert_eq!(parse_two(&["./argparse_test", "10"]), (10, 2)); assert_eq!(parse_two(&["./argparse_test", "11", "21"]), (11, 21)); } #[test] #[should_panic] fn test_two_fail_many() { parse_two(&["./argparse_test", "10", "20", "30"]); } #[test] #[should_panic] fn test_two_fail_value() { parse_two(&["./argparse_test", "test", "20"]); } #[test] #[should_panic] fn test_two_fail_float() { parse_two(&["./argparse_test", "1.5"]); } fn parse_pos_opt(args: &[&str]) -> (isize, isize) { let mut val1 = 1; let mut val2 = 2; { let mut ap = ArgumentParser::new(); ap.refer(&mut val1) .add_option(&["--v1"], Store, "The value 1") .add_argument("v1", Store, "The value 1"); ap.refer(&mut val2) .add_argument("v2", Store, "The value 2"); check_ok(&ap, args); } return (val1, val2); } #[test] fn test_positional_optional() { assert_eq!(parse_pos_opt(&["./argparse_test", "10"]), (10, 2)); assert_eq!(parse_pos_opt(&["./argparse_test", "11", "21"]), (11, 21)); assert_eq!(parse_pos_opt(&["./argparse_test", "--v1=7", "8"]), (7, 8)); assert_eq!(parse_pos_opt(&["./argparse_test", "10", "--v1=9"]), (9, 10)); } #[test] #[should_panic] fn test_pos_opt_err() { parse_pos_opt(&["./argparse_test", "--v1=10", "20", "30"]); } fn parse_pos_req(args: &[&str]) -> (isize, isize) { let mut val1 = 1; let mut val2 = 2; { let mut ap = ArgumentParser::new(); ap.refer(&mut val1) .add_option(&["--v1"], Store, "The value 1") .add_argument("v1", Store, "The value 1") .required(); ap.refer(&mut val2) .add_argument("v2", Store, "The value 2"); check_ok(&ap, args); } return (val1, val2); } #[test] fn test_positional_required() { assert_eq!(parse_pos_req(&["./argparse_test", "10"]), (10, 2)); assert_eq!(parse_pos_req(&["./argparse_test", "11", "21"]), (11, 21)); assert_eq!(parse_pos_req(&["./argparse_test", "--v1=7"]), (7, 2)); assert_eq!(parse_pos_req(&["./argparse_test", "10", "--v1=9"]), (9, 10)); } #[test] #[should_panic] fn test_pos_extra() { parse_pos_req(&["./argparse_test", "--v1=10", "20", "30"]); } #[test] #[should_panic] fn test_pos_no_req() { parse_pos_req(&["./argparse_test"]); } fn pos_stop(args: &[&str]) -> (isize, Vec) { let mut val1 = 1; let mut val2 = Vec::new(); { let mut ap = ArgumentParser::new(); ap.refer(&mut val1) .add_option(&["--v1"], Store, "The value 1") .add_argument("v1", Store, "The value 1") .required(); ap.refer(&mut val2) .add_argument("v2", List, "The value 2"); ap.stop_on_first_argument(true); check_ok(&ap, args); } return (val1, val2); } #[test] fn test_pos_stop() { assert_eq!(pos_stop(&["./argparse_test", "10"]), (10, vec!())); assert_eq!(pos_stop(&["./argparse_test", "11", "21"]), (11, vec!("21".to_string()))); assert_eq!(pos_stop(&["./argparse_test", "--v1=7"]), (7, vec!())); assert_eq!(pos_stop(&["./argparse_test", "10", "--v1=9", "--whatever"]), (10, vec!("--v1=9".to_string(), "--whatever".to_string()))); } #[test] #[should_panic] fn test_test() { pos_stop(&["./argparse_test"]); } fn pos_dash(args: &[&str], dash: bool) -> Vec { let mut val = Vec::new(); { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_argument("v1", List, "The value"); ap.silence_double_dash(dash); check_ok(&ap, args); } return val; } #[test] fn test_pos_dash() { assert_eq!(pos_dash(&["./argparse_test", "1"], true), vec!("1".to_string())); assert_eq!(pos_dash(&["./argparse_test", "--", "1"], true), vec!("1".to_string())); assert_eq!(pos_dash(&["./argparse_test", "--", "1"], false), vec!("--".to_string(), "1".to_string())); } argparse-0.2.2/src/test_str.rs010064400037200003720000000012321334216370200145410ustar0000000000000000use parser::ArgumentParser; use super::Store; use test_parser::{check_ok}; fn parse_str(args: &[&str]) -> String { let mut val: String = "".to_string(); { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["-s", "--set"], Store, "Set string value"); check_ok(&ap, args); } return val; } #[test] fn test_str() { assert_eq!(parse_str(&["./argparse_test", "-s", "10"]), "10".to_string()); assert_eq!(parse_str(&["./argparse_test", "--set", "value"]), "value".to_string()); } #[test] #[should_panic] fn test_err() { parse_str(&["./argparse_test", "--set"]); } argparse-0.2.2/src/test_usage.rs010064400037200003720000000031011334216370200150320ustar0000000000000000use std::str::from_utf8; use parser::ArgumentParser; use super::{Store, List}; #[test] fn test_empty() { let ap = ArgumentParser::new(); let mut buf = Vec::::new(); assert!(ap.print_usage("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n ./argparse_test\n", from_utf8(&buf[..]).unwrap()); } #[test] fn test_options() { let mut val = 0; let mut buf = Vec::::new(); { let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_option(&["--value"], Store, "Set integer value"); assert!(ap.print_usage("./argparse_test", &mut buf).is_ok()); } assert_eq!("Usage:\n ./argparse_test [OPTIONS]\n", from_utf8(&buf[..]).unwrap()); } #[test] fn test_argument() { let mut val = 0; let mut ap = ArgumentParser::new(); ap.refer(&mut val) .add_argument("value", Store, "Integer value"); let mut buf = Vec::::new(); assert!(ap.print_usage("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n ./argparse_test [VALUE]\n", from_utf8(&buf[..]).unwrap()); } #[test] fn test_arguments() { let mut v1 = 0; let mut v2 = Vec::::new(); let mut ap = ArgumentParser::new(); ap.refer(&mut v1) .add_argument("v1", Store, "Integer value 1"); ap.refer(&mut v2) .add_argument("v2", List, "More values"); let mut buf = Vec::::new(); assert!(ap.print_usage("./argparse_test", &mut buf).is_ok()); assert_eq!("Usage:\n ./argparse_test [V1] [V2 ...]\n", from_utf8(&buf[..]).unwrap()); } argparse-0.2.2/vagga.yaml010064400037200003720000000030701334216370200135100ustar0000000000000000containers: build: setup: - !Ubuntu bionic - !Install [build-essential, ca-certificates, vim] - !TarInstall url: https://static.rust-lang.org/dist/rust-1.28.0-x86_64-unknown-linux-gnu.tar.gz # We install rustc and cargo, but skip rust-docs script: "./install.sh --prefix=/usr \ --components=rustc,rust-std-x86_64-unknown-linux-gnu,cargo" - &bulk !Tar url: "https://github.com/tailhook/bulk/releases/download/v0.4.12/bulk-v0.4.12.tar.gz" sha256: 7deeb4895b3909afea46194ef01bafdeb30ff89fc4a7b6497172ba117734040e path: / environ: HOME: /work/run volumes: /tmp: !Tmpfs { size: 100Mi } commands: make: !Command description: Build the library container: build run: [cargo, build] test: !Command description: Run the tests container: build run: [cargo, test] cargo: !Command container: build run: [cargo] example-greeting: !Command description: Build and run "greeting" example container: build accepts-arguments: true run: [cargo, run, --example, greeting, "--"] example-structure: !Command description: Build and run "structure" example container: build accepts-arguments: true run: [cargo, run, --example, structure, "--"] example-subcommands: !Command description: Build and run "subcommands" example container: build accepts-arguments: true run: [cargo, run, --example, subcommands, "--"] _bulk: !Command description: Run `bulk` command (for version bookkeeping) container: build run: [bulk]