diff options
Diffstat (limited to 'argparse')
34 files changed, 0 insertions, 3274 deletions
diff --git a/argparse/.gitignore b/argparse/.gitignore deleted file mode 100644 index 6ae6389..0000000 --- a/argparse/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -/.vagga -*.o -*.so -*.rlib -/argparse_test -/target -# examples -/greeting -/structure -/subcommands - -# Cargo files -Cargo.lock diff --git a/argparse/.travis.yml b/argparse/.travis.yml deleted file mode 100644 index 7ccbf43..0000000 --- a/argparse/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -sudo: 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 diff --git a/argparse/Cargo.toml b/argparse/Cargo.toml deleted file mode 100644 index 7552373..0000000 --- a/argparse/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[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 <paul@colomiets.name>"] - diff --git a/argparse/LICENSE b/argparse/LICENSE deleted file mode 100644 index 3e00de4..0000000 --- a/argparse/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (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. diff --git a/argparse/README.rst b/argparse/README.rst deleted file mode 100644 index 8a3fca0..0000000 --- a/argparse/README.rst +++ /dev/null @@ -1,341 +0,0 @@ -======== -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<T>(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<i32> = 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<int>`` 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"); - - diff --git a/argparse/bulk.yaml b/argparse/bulk.yaml deleted file mode 100644 index 73a7d02..0000000 --- a/argparse/bulk.yaml +++ /dev/null @@ -1,11 +0,0 @@ -minimum-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+)" diff --git a/argparse/examples/greeting.rs b/argparse/examples/greeting.rs deleted file mode 100644 index 77e719c..0000000 --- a/argparse/examples/greeting.rs +++ /dev/null @@ -1,26 +0,0 @@ -extern 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); -} diff --git a/argparse/examples/structure.rs b/argparse/examples/structure.rs deleted file mode 100644 index 59b9345..0000000 --- a/argparse/examples/structure.rs +++ /dev/null @@ -1,38 +0,0 @@ -extern 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); -} diff --git a/argparse/examples/subcommands.rs b/argparse/examples/subcommands.rs deleted file mode 100644 index 8fb061a..0000000 --- a/argparse/examples/subcommands.rs +++ /dev/null @@ -1,88 +0,0 @@ -use 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<Command, ()> { - return match src { - "play" => Ok(Command::play), - "record" => Ok(Command::record), - _ => Err(()), - }; - } -} - - - -fn play_command(verbose: bool, args: Vec<String>) { - 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<String>) { - 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), - } -} diff --git a/argparse/src/action.rs b/argparse/src/action.rs deleted file mode 100644 index c3a0aff..0000000 --- a/argparse/src/action.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::cell::RefCell; -use std::rc::Rc; - -pub enum ParseResult { - Parsed, - Help, - Exit, - Error(String), -} - - -pub enum Action<'a> { - Flag(Box<IFlagAction + 'a>), - Single(Box<IArgAction + 'a>), - Push(Box<IArgsAction + 'a>), - Many(Box<IArgsAction + 'a>), -} - -pub trait TypedAction<T> { - fn bind<'x>(&self, Rc<RefCell<&'x mut T>>) -> 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; -} diff --git a/argparse/src/bool.rs b/argparse/src/bool.rs deleted file mode 100644 index 6ada458..0000000 --- a/argparse/src/bool.rs +++ /dev/null @@ -1,22 +0,0 @@ -use 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<bool> for StoreTrue { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut bool>>) -> Action<'x> { - return Flag(Box::new(StoreConstAction { cell: cell, value: true })); - } -} - -impl TypedAction<bool> for StoreFalse { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut bool>>) -> Action<'x> { - return Flag(Box::new(StoreConstAction { cell: cell, value: false })); - } -} - diff --git a/argparse/src/custom.rs b/argparse/src/custom.rs deleted file mode 100644 index d002ffe..0000000 --- a/argparse/src/custom.rs +++ /dev/null @@ -1,95 +0,0 @@ -use 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<RefCell<&'a mut T>>, -} - -pub struct ParseOptionAction<'a, T: 'a> { - cell: Rc<RefCell<&'a mut Option<T>>>, -} - -pub struct ParseListAction<'a, T: 'a> { - cell: Rc<RefCell<&'a mut Vec<T>>>, -} - -impl<T: 'static + FromCommandLine> TypedAction<T> for Parse { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut T>>) -> Action<'x> { - return Single(Box::new(ParseAction { cell: cell })); - } -} - -impl<T: 'static + FromCommandLine> TypedAction<Option<T>> for ParseOption { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Option<T>>>) -> Action<'x> { - return Single(Box::new(ParseOptionAction { cell: cell })); - } -} - -impl<T: 'static + FromCommandLine + Clone> TypedAction<Vec<T>> for ParseList { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Vec<T>>>) -> Action<'x> { - return Many(Box::new(ParseListAction { cell: cell })); - } -} - -impl<T> TypedAction<Vec<T>> for ParseCollect - where T: 'static + FromCommandLine + Clone -{ - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Vec<T>>>) -> 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; - } -} - - diff --git a/argparse/src/from_cli.rs b/argparse/src/from_cli.rs deleted file mode 100644 index 7ea6d58..0000000 --- a/argparse/src/from_cli.rs +++ /dev/null @@ -1,100 +0,0 @@ -use 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<Self, String> { - Ok(From::from(s)) - } -} - -impl FromCommandLine for f32 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for f64 { - fn from_argument(s: &str) -> Result<Self, String> { - 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<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for i8 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for i16 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for i32 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for i64 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for usize { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for u8 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for u16 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for u32 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for u64 { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for bool { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for String { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|_| unreachable!()) - } -} -impl FromCommandLine for Ipv4Addr { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for Ipv6Addr { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} -impl FromCommandLine for SocketAddr { - fn from_argument(s: &str) -> Result<Self, String> { - FromStr::from_str(s).map_err(|e| format!("{:?}", e)) - } -} diff --git a/argparse/src/generic.rs b/argparse/src/generic.rs deleted file mode 100644 index 1b1b7dc..0000000 --- a/argparse/src/generic.rs +++ /dev/null @@ -1,133 +0,0 @@ -use 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<RefCell<&'a mut T>>, -} - -pub struct PushConstAction<'a, T: 'a> { - pub value: T, - pub cell: Rc<RefCell<&'a mut Vec<T>>>, -} - -pub struct StoreAction<'a, T: 'a> { - pub cell: Rc<RefCell<&'a mut T>>, -} - -pub struct StoreOptionAction<'a, T: 'a> { - cell: Rc<RefCell<&'a mut Option<T>>>, -} - -pub struct ListAction<'a, T: 'a> { - cell: Rc<RefCell<&'a mut Vec<T>>>, -} - -impl<T: 'static + Clone> TypedAction<T> for StoreConst<T> { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut T>>) -> Action<'x> { - let StoreConst(ref val) = *self; - return Flag(Box::new(StoreConstAction { cell: cell, value: val.clone() })); - } -} - -impl<T: 'static + Clone> TypedAction<Vec<T>> for PushConst<T> { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Vec<T>>>) -> Action<'x> { - let PushConst(ref val) = *self; - return Flag(Box::new(PushConstAction { cell: cell, value: val.clone() })); - } -} - -impl<T: 'static + FromStr> TypedAction<T> for Store { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut T>>) -> Action<'x> { - return Single(Box::new(StoreAction { cell: cell })); - } -} - -impl<T: 'static + FromStr> TypedAction<Option<T>> for StoreOption { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Option<T>>>) -> Action<'x> { - return Single(Box::new(StoreOptionAction { cell: cell })); - } -} - -impl<T: 'static + FromStr + Clone> TypedAction<Vec<T>> for List { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Vec<T>>>) -> Action<'x> { - return Many(Box::new(ListAction { cell: cell })); - } -} - -impl<T: 'static + FromStr + Clone> TypedAction<Vec<T>> for Collect { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut Vec<T>>>) -> 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; - } -} - diff --git a/argparse/src/help.rs b/argparse/src/help.rs deleted file mode 100644 index c7145be..0000000 --- a/argparse/src/help.rs +++ /dev/null @@ -1,93 +0,0 @@ -use 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(()); -} diff --git a/argparse/src/lib.rs b/argparse/src/lib.rs deleted file mode 100644 index 62b0cf9..0000000 --- a/argparse/src/lib.rs +++ /dev/null @@ -1,64 +0,0 @@ -#![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<Self, String>; -} - -// TODO(tailhook) make consts -pub struct StoreTrue; -pub struct StoreFalse; - -pub struct StoreConst<T>(pub T); - -pub struct PushConst<T>(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<T>(pub T); - -pub struct DecrBy<T>(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; diff --git a/argparse/src/num.rs b/argparse/src/num.rs deleted file mode 100644 index 9f34de7..0000000 --- a/argparse/src/num.rs +++ /dev/null @@ -1,58 +0,0 @@ -use 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<RefCell<&'a mut T>>, -} - -pub struct DecrByAction<'a, T: 'a> { - delta: T, - cell: Rc<RefCell<&'a mut T>>, -} - -impl<T: 'static + Add<Output = T> + Clone> TypedAction<T> for IncrBy<T> { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut T>>) -> Action<'x> { - let IncrBy(ref delta) = *self; - return Flag(Box::new(IncrByAction { cell: cell, delta: delta.clone() })); - } -} - -impl<T: 'static + Sub<Output = T> + Clone> TypedAction<T> for DecrBy<T> { - fn bind<'x>(&self, cell: Rc<RefCell<&'x mut T>>) -> Action<'x> { - let DecrBy(ref delta) = *self; - return Flag(Box::new(DecrByAction { cell: cell, delta: delta.clone() })); - } -} - -impl<'a, T: Add<Output = T> + 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<Output = T> + 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; - } -} - diff --git a/argparse/src/parser.rs b/argparse/src/parser.rs deleted file mode 100644 index ac7e3da..0000000 --- a/argparse/src/parser.rs +++ /dev/null @@ -1,967 +0,0 @@ -use 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<usize>, - names: Vec<&'parser str>, - help: &'parser str, - action: Action<'parser>, -} - -struct EnvVar<'parser> { - varid: usize, - name: &'parser str, - action: Box<IArgAction + 'parser>, -} - -impl<'a> Hash for GenericOption<'a> { - fn hash<H>(&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<H>(&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<H>(&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<usize>, - list_options: HashMap<Rc<GenericOption<'parser>>, Vec<&'ctx str>>, - list_arguments: HashMap<Rc<GenericArgument<'parser>>, Vec<&'ctx str>>, - arguments: Vec<&'ctx str>, - iter: Peekable<Iter<'ctx, String>>, - stderr: &'ctx mut (Write + 'ctx), -} - -impl<'a, 'b> Context<'a, 'b> { - - fn parse_option(&mut self, opt: Rc<GenericOption<'b>>, - 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<String>, 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<RefCell<&'parser mut T>>, - varid: usize, - parser: &'refer mut ArgumentParser<'parser>, -} - -impl<'parser, 'refer, T> Ref<'parser, 'refer, T> { - - pub fn add_option<'x, A: TypedAction<T>>(&'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<T>>(&'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<Box<Var>>, - options: Vec<Rc<GenericOption<'parser>>>, - arguments: Vec<Rc<GenericArgument<'parser>>>, - env_vars: Vec<Rc<EnvVar<'parser>>>, - catchall_argument: Option<Rc<GenericArgument<'parser>>>, - short_options: HashMap<char, Rc<GenericOption<'parser>>>, - long_options: HashMap<String, Rc<GenericOption<'parser>>>, - 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<Ref<'parser, 'x, T>> - { - 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<F:IFlagAction + 'parser>(&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<usize>, - 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<String>, - 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(()); - } - -} diff --git a/argparse/src/print.rs b/argparse/src/print.rs deleted file mode 100644 index d0335c5..0000000 --- a/argparse/src/print.rs +++ /dev/null @@ -1,13 +0,0 @@ -use 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; - } -} diff --git a/argparse/src/test_bool.rs b/argparse/src/test_bool.rs deleted file mode 100644 index a30cf3c..0000000 --- a/argparse/src/test_bool.rs +++ /dev/null @@ -1,98 +0,0 @@ -use 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"])); -} diff --git a/argparse/src/test_const.rs b/argparse/src/test_const.rs deleted file mode 100644 index b12e3d8..0000000 --- a/argparse/src/test_const.rs +++ /dev/null @@ -1,28 +0,0 @@ -use parser::ArgumentParser; -use super::{PushConst}; -use test_parser::{check_ok}; - - -fn push_const(args: &[&str]) -> Vec<u32> { - 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)); -} diff --git a/argparse/src/test_enum.rs b/argparse/src/test_enum.rs deleted file mode 100644 index 5205738..0000000 --- a/argparse/src/test_enum.rs +++ /dev/null @@ -1,51 +0,0 @@ -use 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<Greeting, ()> { - 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"]); -} diff --git a/argparse/src/test_env.rs b/argparse/src/test_env.rs deleted file mode 100644 index 2e1b649..0000000 --- a/argparse/src/test_env.rs +++ /dev/null @@ -1,43 +0,0 @@ -use 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"); -} diff --git a/argparse/src/test_float.rs b/argparse/src/test_float.rs deleted file mode 100644 index 9ef0f56..0000000 --- a/argparse/src/test_float.rs +++ /dev/null @@ -1,50 +0,0 @@ -use 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"]); -} diff --git a/argparse/src/test_help.rs b/argparse/src/test_help.rs deleted file mode 100644 index f23b14b..0000000 --- a/argparse/src/test_help.rs +++ /dev/null @@ -1,154 +0,0 @@ -use std::str::from_utf8; - -use parser::ArgumentParser; -use super::{Store, List}; - -#[test] -fn test_empty() { - let mut ap = ArgumentParser::new(); - let mut buf = Vec::<u8>::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::<u8>::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::<u8>::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::<u32>::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::<u8>::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::<u32>::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::<u8>::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::<u8>::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()); -} diff --git a/argparse/src/test_int.rs b/argparse/src/test_int.rs deleted file mode 100644 index 1826eaf..0000000 --- a/argparse/src/test_int.rs +++ /dev/null @@ -1,107 +0,0 @@ -use 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"]); -} diff --git a/argparse/src/test_many.rs b/argparse/src/test_many.rs deleted file mode 100644 index 68e2cec..0000000 --- a/argparse/src/test_many.rs +++ /dev/null @@ -1,95 +0,0 @@ -use parser::ArgumentParser; -use super::{List, Store, Collect}; -use test_parser::{check_ok}; - -fn pos_list(args: &[&str]) -> (isize, Vec<isize>) { - 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<isize> { - 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<isize> { - 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<isize> { - 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)); -} diff --git a/argparse/src/test_optional.rs b/argparse/src/test_optional.rs deleted file mode 100644 index 5f4c35e..0000000 --- a/argparse/src/test_optional.rs +++ /dev/null @@ -1,54 +0,0 @@ -use parser::ArgumentParser; -use super::StoreOption; -use test_parser::{check_ok}; - -fn opt(args: &[&str]) -> Option<isize> { - 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<String> { - 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"]); -} diff --git a/argparse/src/test_parser.rs b/argparse/src/test_parser.rs deleted file mode 100644 index f60aa64..0000000 --- a/argparse/src/test_parser.rs +++ /dev/null @@ -1,64 +0,0 @@ - -use parser::ArgumentParser; - -pub fn check_ok(ap: &ArgumentParser, args: &[&str]) { - let mut stdout = Vec::<u8>::new(); - let mut stderr = Vec::<u8>::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::<u8>::new(); - let mut stderr = Vec::<u8>::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::<u8>::new(); - let mut stderr = Vec::<u8>::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"]); -} diff --git a/argparse/src/test_path.rs b/argparse/src/test_path.rs deleted file mode 100644 index 868ae8c..0000000 --- a/argparse/src/test_path.rs +++ /dev/null @@ -1,30 +0,0 @@ -use 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"]); -} diff --git a/argparse/src/test_pos.rs b/argparse/src/test_pos.rs deleted file mode 100644 index 2542050..0000000 --- a/argparse/src/test_pos.rs +++ /dev/null @@ -1,196 +0,0 @@ -use 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<String>) { - 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<String> { - 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())); -} diff --git a/argparse/src/test_str.rs b/argparse/src/test_str.rs deleted file mode 100644 index 42db286..0000000 --- a/argparse/src/test_str.rs +++ /dev/null @@ -1,28 +0,0 @@ -use 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"]); -} diff --git a/argparse/src/test_usage.rs b/argparse/src/test_usage.rs deleted file mode 100644 index efe89fe..0000000 --- a/argparse/src/test_usage.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::str::from_utf8; - -use parser::ArgumentParser; -use super::{Store, List}; - -#[test] -fn test_empty() { - let ap = ArgumentParser::new(); - let mut buf = Vec::<u8>::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::<u8>::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::<u8>::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::<u32>::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::<u8>::new(); - assert!(ap.print_usage("./argparse_test", &mut buf).is_ok()); - assert_eq!("Usage:\n ./argparse_test [V1] [V2 ...]\n", - from_utf8(&buf[..]).unwrap()); -} diff --git a/argparse/vagga.yaml b/argparse/vagga.yaml deleted file mode 100644 index c6e0c52..0000000 --- a/argparse/vagga.yaml +++ /dev/null @@ -1,59 +0,0 @@ -containers: - - 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] |