Skip to content

Commit

Permalink
wip: macro reworking
Browse files Browse the repository at this point in the history
  • Loading branch information
kbknapp committed Jan 22, 2016
1 parent ffe7950 commit 12f8d55
Show file tree
Hide file tree
Showing 23 changed files with 226 additions and 396 deletions.
2 changes: 1 addition & 1 deletion benches/03_complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ macro_rules! create_app {
.args_from_usage(ARGS)
.arg(Arg::from_usage("-f --flag... 'tests flags'")
.global(true))
.args(vec![
.args(&[
Arg::from_usage("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("option2"),
Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
Arg::from_usage("[positional2] 'tests positionals with exclusions'"),
Expand Down
2 changes: 1 addition & 1 deletion clap-tests/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn main() {
.args_from_usage(args)
.arg(Arg::from_usage("-f --flag... 'tests flags'")
.global(true))
.args(vec![
.args(&[
Arg::from_usage("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("option2"),
Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
Arg::from_usage("[positional2] 'tests positionals with exclusions'"),
Expand Down
1 change: 1 addition & 0 deletions examples/01c_quick_example.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[macro_use]
extern crate clap;

#[cfg(feature = "nightly")]
fn main() {
// This example shows how to create an application with several arguments using macro builder.
// It combines the simplicity of the from_usage methods and the performance of the Builder Pattern.
Expand Down
2 changes: 1 addition & 1 deletion examples/03_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn main() {

// Two arguments, one "Option" argument (i.e. one that takes a value) such
// as "-c some", and one positional argument (i.e. "myapp some_file")
.args( vec![
.args( &[
Arg::with_name("config")
.help("sets the config file to use")
.takes_value(true)
Expand Down
4 changes: 2 additions & 2 deletions examples/07_option_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ fn main() {
}

// If we specified the multiple() setting we can get all the values
if let Some(ref in_v) = matches.values_of("input") {
for in_file in in_v.iter() {
if let Some(in_v) = matches.values_of("input") {
for in_file in in_v {
println!("An input file: {}", in_file);
}
}
Expand Down
25 changes: 16 additions & 9 deletions examples/13a_enum_values_automatic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ extern crate clap;

use clap::{App, Arg};

// Define your enum, the simple_num! macro takes a enum name followed by => and each value
// separated by a ','
simple_enum!{ Foo => Bar, Baz, Qux }

// Using arg_enum! is more like traditional enum declarations
//
// **NOTE:** Only bare variants are supported
Expand All @@ -31,22 +27,33 @@ arg_enum!{
}
}

arg_enum!{
#[derive(Debug)]
enum Foo {
Bar,
Baz,
Qux
}
}

fn main() {
// Create the application like normal
let enum_vals = ["fast", "slow"];
let m = App::new("myapp")
// Use a single positional argument that is required
.arg(Arg::from_usage("<type> 'The Foo to use'")
.arg(Arg::from_usage("<foo> 'The Foo to use'")
.possible_values(&*Foo::variants()))
.arg(Arg::from_usage("<speed> 'The speed to use'")
// You can define a list of possible values if you want the values to be
// displayed in the help information. Whether you use possible_values() or
// not, the valid values will ALWAYS be displayed on a failed parse.
.possible_values(&enum_vals))
// For the second positional, lets not use possible_values() just to show the difference
.arg_from_usage("<type2> 'The Oof to use'")
.arg_from_usage("<oof> 'The Oof to use'")
.get_matches();

let t = value_t_or_exit!(m.value_of("type"), Foo);
let t2 = value_t_or_exit!(m.value_of("type2"), Oof);
let t = value_t!(m.value_of("foo"), Foo).unwrap_or_else(|e| e.exit());
let t2 = value_t!(m.value_of("oof"), Oof).unwrap_or_else(|e| e.exit());


// Now we can use our enum like normal.
Expand All @@ -58,4 +65,4 @@ fn main() {

// Since our Oof derives Debug, we can do this:
println!("Oof: {:?}", t2);
}
}
7 changes: 2 additions & 5 deletions examples/13b_enum_values_manual.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// If you require more complex configuration than simple_enum! provides, you can implement the
// trait manually, as in the following example.
//
// In the following example we will create an enum with 4 values, assign a positional argument
// that accepts only one of those values, and use clap to parse the argument.
//
Expand Down Expand Up @@ -46,7 +43,7 @@ fn main() {
.possible_values(&enum_vals))
.get_matches();

let t = value_t_or_exit!(m.value_of("type"), Vals);
let t = value_t!(m.value_of("type"), Vals).or_else(|e| e.exit());

// Now we can use our enum like normal.
match t {
Expand All @@ -55,4 +52,4 @@ fn main() {
Vals::Baz => println!("Found a Baz"),
Vals::Qux => println!("Found a Qux")
}
}
}
7 changes: 5 additions & 2 deletions examples/18_builder_macro.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#[macro_use] extern crate clap;
#[macro_use]
extern crate clap;

// No use imports from clap. #[macro_use] gives us `clap_app!` which internally uses `$crate::`
// Note, there isn't a need for "use clap::{ ... };" Because the clap_app! macro uses
// $crate:: internally

#[cfg(feature = "nightly")]
fn main() {

// Validation example testing that a file exists
Expand Down
12 changes: 6 additions & 6 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,8 +699,8 @@ impl<'a, 'b> App<'a, 'b> {
/// // Args and options go here...
/// .get_matches_from(arg_vec);
/// ```
pub fn get_matches_from<I, T>(mut self, itr: &mut I) -> ArgMatches<'a>
where I: Iterator<Item = T>,
pub fn get_matches_from<I, T>(mut self, itr: I) -> ArgMatches<'a>
where I: IntoIterator<Item = T>,
T: Into<OsString>
{
self.get_matches_from_safe_borrow(itr).unwrap_or_else(|e| {
Expand Down Expand Up @@ -741,8 +741,8 @@ impl<'a, 'b> App<'a, 'b> {
/// .get_matches_from_safe(arg_vec)
/// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) });
/// ```
pub fn get_matches_from_safe<I, T>(mut self, itr: &mut I) -> ClapResult<ArgMatches<'a>>
where I: Iterator<Item = T>,
pub fn get_matches_from_safe<I, T>(mut self, itr: I) -> ClapResult<ArgMatches<'a>>
where I: IntoIterator<Item = T>,
T: Into<OsString>
{
self.get_matches_from_safe_borrow(itr)
Expand Down Expand Up @@ -775,8 +775,8 @@ impl<'a, 'b> App<'a, 'b> {
/// let matches = app.get_matches_from_safe_borrow(arg_vec)
/// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) });
/// ```
fn get_matches_from_safe_borrow<I, T>(&mut self, itr: &mut I) -> ClapResult<ArgMatches<'a>>
where I: Iterator<Item = T>,
pub fn get_matches_from_safe_borrow<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches<'a>>
where I: IntoIterator<Item = T>,
T: Into<OsString>
{
// Verify all positional assertions pass
Expand Down
2 changes: 1 addition & 1 deletion src/args/arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ impl<'a, 'b> Arg<'a, 'b> {
/// ```no_run
/// # use clap::{App, Arg};
/// # let matches = App::new("myprog")
/// .args(vec![
/// .args(&[
///
/// // A option argument with a long, named "conf" (note: because the name was specified
/// // the portion after the long can be called anything, only the first name will be displayed
Expand Down
32 changes: 11 additions & 21 deletions src/args/arg_matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::HashMap;
use std::iter::Map;
use std::slice;

use vec_map::{self, VecMap};
use vec_map;

use args::SubCommand;
use args::MatchedArg;
Expand Down Expand Up @@ -66,9 +66,6 @@ pub struct ArgMatches<'a> {
pub subcommand: Option<Box<SubCommand<'a>>>,
#[doc(hidden)]
pub usage: Option<String>,
#[doc(hidden)]
empty_v: VecMap<OsString>,
// utf8: Utf8,
}

impl<'a> Default for ArgMatches<'a> {
Expand All @@ -77,10 +74,6 @@ impl<'a> Default for ArgMatches<'a> {
args: HashMap::new(),
subcommand: None,
usage: None,
// utf8: Utf8::Strict,
// utf8_rule: PhantomData::<utf8::Strict>,
empty_v: VecMap::new(),
// empty_ov: VecMap::new(),
}
}
}
Expand Down Expand Up @@ -149,34 +142,31 @@ impl<'a> ArgMatches<'a> {
/// }
/// }
/// ```
pub fn values_of<S: AsRef<str>>(&'a self, name: S) -> Values<'a> {
pub fn values_of<S: AsRef<str>>(&'a self, name: S) -> Option<Values<'a>> {
if let Some(ref arg) = self.args.get(name.as_ref()) {
fn to_str_slice<'a>(o: &'a OsString) -> &'a str { o.to_str().expect(INVALID_UTF8) }
let to_str_slice: fn(&'a OsString) -> &'a str = to_str_slice; // coerce to fn pointer
return Values { iter: arg.vals.values().map(to_str_slice) };
return Some(Values { iter: arg.vals.values().map(to_str_slice) });
}
fn to_str_slice<'a>(o: &'a OsString) -> &'a str { o.to_str().expect(INVALID_UTF8) }
let to_str_slice: fn(&'a OsString) -> &'a str = to_str_slice; // coerce to fn pointer
Values { iter: self.empty_v.values().map(to_str_slice) }
None
}

pub fn lossy_values_of<S: AsRef<str>>(&'a self, name: S) -> Vec<String> {
pub fn lossy_values_of<S: AsRef<str>>(&'a self, name: S) -> Option<Vec<String>> {
if let Some(ref arg) = self.args.get(name.as_ref()) {
return arg.vals.values()
return Some(arg.vals.values()
.map(|v| v.to_string_lossy().into_owned())
// .map(ToOwned::to_owned)
.collect();
.collect());
}
vec![]
None
}

pub fn os_values_of<S: AsRef<str>>(&'a self, name: S) -> OsValues<'a> {
pub fn os_values_of<S: AsRef<str>>(&'a self, name: S) -> Option<OsValues<'a>> {
fn to_str_slice<'a>(o: &'a OsString) -> &'a OsStr { &*o }
let to_str_slice: fn(&'a OsString) -> &'a OsStr = to_str_slice; // coerce to fn pointer
if let Some(ref arg) = self.args.get(name.as_ref()) {
return OsValues { iter: arg.vals.values().map(to_str_slice) }
return Some(OsValues { iter: arg.vals.values().map(to_str_slice) });
}
OsValues { iter: self.empty_v.values().map(to_str_slice) }
None
}

/// Returns if an argument was present at runtime.
Expand Down
Loading

0 comments on commit 12f8d55

Please sign in to comment.