Skip to content
This repository was archived by the owner on May 11, 2020. It is now read-only.

Commit

Permalink
Merge pull request #12 from kbknapp/intial-rename
Browse files Browse the repository at this point in the history
Intial rename
  • Loading branch information
kbknapp authored Jul 2, 2018
2 parents d8ec4ad + 49c975a commit abda074
Show file tree
Hide file tree
Showing 40 changed files with 1,231 additions and 1,103 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ If you are using a `u64` in your struct to get the number of occurence of a flag

For example
```rust
#[structopt(short = "v", long = "verbose")]
#[clap(short = "v", long = "verbose")]
verbose: u64,
```
must be changed by
```rust
#[structopt(short = "v", long = "verbose", parse(from_occurrences))]
#[clap(short = "v", long = "verbose", parse(from_occurrences))]
verbose: u64,
```

Expand All @@ -89,7 +89,7 @@ There was no reason to take the argument by value. Most of the StructOpt users w

### Fail if attributes are not used by [@TeXitoi](https://github.com/TeXitoi)

StructOpt was quite fuzzy in its attribute parsing: it was only searching for interresting things, e. g. something like `#[structopt(foo(bar))]` was accepted but not used. It now fails the compilation.
StructOpt was quite fuzzy in its attribute parsing: it was only searching for interresting things, e. g. something like `#[clap(foo(bar))]` was accepted but not used. It now fails the compilation.

You should have nothing to do here. This breaking change may highlight some missuse that can be bugs.

Expand Down
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ appveyor = { repository = "https://github.com/kbknapp/clap_derive", service = "g
syn = "0.14"
quote = "0.6"
proc-macro2 = "0.4"
clippy = {version = "0.174",optional = true}
clippy = {version = "0.0.174", optional = true }

[dev-dependencies]
clap = {path = "../clap-rs"} # ONLY FOR INITIAL DEVELOPMENT...change to real crates.io ver for rlease!

[features]
default = []
nightly = []
lints = ["clippy"]
debug = []
doc = ["doc"]
doc = []
56 changes: 31 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,72 @@
# StructOpt [![Build status](https://travis-ci.org/TeXitoi/structopt.svg?branch=master)](https://travis-ci.org/TeXitoi/structopt) [![](https://img.shields.io/crates/v/structopt.svg)](https://crates.io/crates/structopt) [![](https://docs.rs/structopt/badge.svg)](https://docs.rs/structopt)
# Work in Progress

Parse command line argument by defining a struct. It combines [clap](https://crates.io/crates/clap) with custom derive.
This crate is currently a work in progress and not meant to be used. Please use [`structopt`](https://github.com/TeXitoi/structopt)
while this crate is being built.

# clap_derive[![Build status](https://travis-ci.org/kbknapp/clap_derive.svg?branch=master)](https://travis-ci.org/kbknapp/clap_derive) [![](https://img.shields.io/crates/v/clap_derive.svg)](https://crates.io/crates/clap_derive) [![](https://docs.rs/clap_derive/badge.svg)](https://docs.rs/clap_derive)

Parse command line argument by defining a struct. It combines [structopt](https://github.com/TeXitoi/structopt) and [clap](https://crates.io/crates/clap) into a single experience. This crate is used by clap, and not meant to be used directly by
consumers.

## Documentation

Find it on [Docs.rs](https://docs.rs/structopt). You can also check the [examples](https://github.com/TeXitoi/structopt/tree/master/examples) and the [changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md).
Find it on [Docs.rs](https://docs.rs/clap_derive). You can also check the [examples](https://github.com/kbknapp/clap_derive/tree/master/examples) and the [changelog](https://github.com/kbknapp/clap_derive/blob/master/CHANGELOG.md).

## Example

Add `structopt` to your dependencies of your `Cargo.toml`:
Add `clap` to your dependencies of your `Cargo.toml`:

```toml
[dependencies]
structopt = "0.2"
clap = "3"
```

And then, in your rust file:
```rust
#[macro_use]
extern crate structopt;
extern crate clap;

use std::path::PathBuf;
use structopt::StructOpt;
use clap::Clap;

/// A basic example
#[derive(StructOpt, Debug)]
#[structopt(name = "basic")]
#[derive(Clap, Debug)]
#[clap(name = "basic")]
struct Opt {
// A flag, true if used in the command line. Note doc comment will
// be used for the help message of the flag.
/// Activate debug mode
#[structopt(short = "d", long = "debug")]
#[clap(short = "d", long = "debug")]
debug: bool,

// The number of occurences of the `v/verbose` flag
/// Verbose mode (-v, -vv, -vvv, etc.)
#[structopt(short = "v", long = "verbose", parse(from_occurrences))]
#[clap(short = "v", long = "verbose", parse(from_occurrences))]
verbose: u8,

/// Set speed
#[structopt(short = "s", long = "speed", default_value = "42")]
#[clap(short = "s", long = "speed", default_value = "42")]
speed: f64,

/// Output file
#[structopt(short = "o", long = "output", parse(from_os_str))]
#[clap(short = "o", long = "output", parse(from_os_str))]
output: PathBuf,

/// Number of cars
#[structopt(short = "c", long = "nb-cars")]
#[clap(short = "c", long = "nb-cars")]
nb_cars: Option<i32>,

/// admin_level to consider
#[structopt(short = "l", long = "level")]
#[clap(short = "l", long = "level")]
level: Vec<String>,

/// Files to process
#[structopt(name = "FILE", parse(from_os_str))]
#[clap(name = "FILE", parse(from_os_str))]
files: Vec<PathBuf>,
}

fn main() {
let opt = Opt::from_args();
let opt = Opt::parse();
println!("{:?}", opt);
}
```
Expand All @@ -82,6 +89,9 @@ A basic example
USAGE:
basic [FLAGS] [OPTIONS] --output <output> [--] [FILE]...
ARGS:
<FILE>... Files to process
FLAGS:
-d, --debug Activate debug mode
-h, --help Prints help information
Expand All @@ -93,24 +103,21 @@ OPTIONS:
-l, --level <level>... admin_level to consider
-o, --output <output> Output file
-s, --speed <speed> Set speed [default: 42]
ARGS:
<FILE>... Files to process
$ ./basic -o foo.txt
Opt { debug: false, verbose: 0, speed: 42, output: "foo.txt", car: None, level: [], files: [] }
$ ./basic -o foo.txt -dvvvs 1337 -l alice -l bob --nb-cars 4 bar.txt baz.txt
Opt { debug: true, verbose: 3, speed: 1337, output: "foo.txt", nb_cars: Some(4), level: ["alice", "bob"], files: ["bar.txt", "baz.txt"] }
```

## StructOpt rustc version policy
## clap_derive rustc version policy

- Minimum rustc version modification must be specified in the [changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) and in the [travis configuration](https://github.com/TeXitoi/structopt/blob/master/.travis.yml).
- Contributors can increment minimum rustc version without any justification if the new version is required by the latest version of one of StructOpt's depedencies (`cargo update` will not fail on StructOpt).
- Minimum rustc version modification must be specified in the [changelog](https://github.com/kbknapp/clap_derive/blob/master/CHANGELOG.md) and in the [travis configuration](https://github.com/kbknapp/clap_derive/blob/master/.travis.yml).
- Contributors can increment minimum rustc version without any justification if the new version is required by the latest version of one of clap_derive's depedencies (`cargo update` will not fail on clap_derive).
- Contributors can increment minimum rustc version if the library user experience is improved.

## Why

I use [docopt](https://crates.io/crates/docopt) since a long time (pre rust 1.0). I really like the fact that you have a structure with the parsed argument: no need to convert `String` to `f64`, no useless `unwrap`. But on the other hand, I don't like to write by hand the usage string. That's like going back to the golden age of WYSIWYG editors. Field naming is also a bit artificial.
I've (@TeXitoi) used [docopt](https://crates.io/crates/docopt) for a long time (pre rust 1.0). I really like the fact that you have a structure with the parsed argument: no need to convert `String` to `f64`, no useless `unwrap`. But on the other hand, I don't like to write by hand the usage string. That's like going back to the golden age of WYSIWYG editors. Field naming is also a bit artificial.

Today, the new standard to read command line arguments in Rust is [clap](https://crates.io/crates/clap). This library is so feature full! But I think there is one downside: even if you can validate argument and expressing that an argument is required, you still need to transform something looking like a hashmap of string vectors to something useful for your application.

Expand All @@ -130,4 +137,3 @@ at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

17 changes: 8 additions & 9 deletions examples/arg_enum_basic.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#[macro_use]
extern crate clap;
#[macro_use]
extern crate clap_derive;

use clap::{App, Arg};

Expand All @@ -14,14 +12,15 @@ enum ArgChoice {

fn main() {
let matches = App::new(env!("CARGO_PKG_NAME"))
.arg(Arg::with_name("arg")
.arg(
Arg::with_name("arg")
.required(true)
.takes_value(true)
.possible_values(&ArgChoice::variants())
).get_matches();

let t = value_t!(matches.value_of("arg"), ArgChoice)
.unwrap_or_else(|e| e.exit());
.possible_values(&ArgChoice::variants()),
)
.get_matches();

let t = value_t!(matches.value_of("arg"), ArgChoice).unwrap_or_else(|e| e.exit());

println!("{:?}", t);
}
}
17 changes: 8 additions & 9 deletions examples/arg_enum_case_sensitive.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#[macro_use]
extern crate clap;
#[macro_use]
extern crate clap_derive;

use clap::{App, Arg};

Expand All @@ -15,14 +13,15 @@ enum ArgChoice {

fn main() {
let matches = App::new(env!("CARGO_PKG_NAME"))
.arg(Arg::with_name("arg")
.arg(
Arg::with_name("arg")
.required(true)
.takes_value(true)
.possible_values(&ArgChoice::variants())
).get_matches();

let t = value_t!(matches.value_of("arg"), ArgChoice)
.unwrap_or_else(|e| e.exit());
.possible_values(&ArgChoice::variants()),
)
.get_matches();

let t = value_t!(matches.value_of("arg"), ArgChoice).unwrap_or_else(|e| e.exit());

println!("{:?}", t);
}
}
10 changes: 5 additions & 5 deletions examples/at_least_two.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#[macro_use]
extern crate structopt;
extern crate clap;

use structopt::StructOpt;
use clap::Clap;

#[derive(StructOpt, Debug)]
#[derive(Clap, Debug)]
struct Opt {
#[structopt(raw(required = "true", min_values = "2"))]
#[clap(raw(required = "true", min_values = "2"))]
foos: Vec<String>,
}

fn main() {
let opt = Opt::from_args();
let opt = Opt::parse();
println!("{:?}", opt);
}
32 changes: 19 additions & 13 deletions examples/basic.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,60 @@
// Copyright 2018 Guillaume Pinot (@TeXitoi) <[email protected]>
// Copyright 2018 Guillaume Pinot (@TeXitoi) <[email protected]>,
// Kevin Knapp (@kbknapp) <[email protected]>, and
// Andrew Hobden (@hoverbear) <[email protected]>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
// MIT/Apache 2.0 license.

#[macro_use]
extern crate structopt;
extern crate clap;

use clap::Clap;
use std::path::PathBuf;
use structopt::StructOpt;

/// A basic example
#[derive(StructOpt, Debug)]
#[structopt(name = "basic")]
#[derive(Clap, Debug)]
#[clap(name = "basic")]
struct Opt {
// A flag, true if used in the command line. Note doc comment will
// be used for the help message of the flag.
/// Activate debug mode
#[structopt(short = "d", long = "debug")]
#[clap(short = "d", long = "debug")]
debug: bool,

// The number of occurences of the `v/verbose` flag
/// Verbose mode (-v, -vv, -vvv, etc.)
#[structopt(short = "v", long = "verbose", parse(from_occurrences))]
#[clap(short = "v", long = "verbose", parse(from_occurrences))]
verbose: u8,

/// Set speed
#[structopt(short = "s", long = "speed", default_value = "42")]
#[clap(short = "s", long = "speed", default_value = "42")]
speed: f64,

/// Output file
#[structopt(short = "o", long = "output", parse(from_os_str))]
#[clap(short = "o", long = "output", parse(from_os_str))]
output: PathBuf,

/// Number of cars
#[structopt(short = "c", long = "nb-cars")]
#[clap(short = "c", long = "nb-cars")]
nb_cars: Option<i32>,

/// admin_level to consider
#[structopt(short = "l", long = "level")]
#[clap(short = "l", long = "level")]
level: Vec<String>,

/// Files to process
#[structopt(name = "FILE", parse(from_os_str))]
#[clap(name = "FILE", parse(from_os_str))]
files: Vec<PathBuf>,
}

fn main() {
let opt = Opt::from_args();
let opt = Opt::parse();
println!("{:?}", opt);
}
Loading

0 comments on commit abda074

Please sign in to comment.