Code Monkey home page Code Monkey logo

thunder's Introduction

clap

Command Line Argument Parser for Rust

Crates.io Crates.io License License Build Status Coverage Status Contributors

Dual-licensed under Apache 2.0 or MIT.

About

Create your command-line parser, with all of the bells and whistles, declaratively or procedurally.

For more details, see:

Sponsors

Gold

Silver

Bronze

Backer

thunder's People

Contributors

enet4 avatar gilescope avatar gugahoa avatar gurry avatar killercup avatar mcampbell avatar rushmorem avatar spacekookie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

thunder's Issues

Commas in custom attribute description breaks

This example

#![feature(proc_macro)]
extern crate thunder;
extern crate clap;

use thunder::thunderclap;

struct Loki;

#[thunderclap(example: Option<String>: "Error here")]
impl Loki {
    fn hello() {
        println!("Hello, {:?}!", Self::example());
    }
}

fn main() {
    Loki::start();
}

This is because of over-simplistic string parsing in the custom attribute parameters 😅

This issue replaced #16

Lifetime parameters on functions cause `thunderclap` attribute to panic

For example, it's not clear how to run app with more than one parameter:

/// App
#[thunderclap]
impl App {
    /// run
    fn run<'a, 'b>(token: &'a str, listening_address: &'b str) {
        println!("Hello {}, my address is {}", token, listening_address);
    }
}
error[E0599]: no function or associated item named `run` found for type `clap::App<'_, '_>` in the current scope
  --> src\main.rs:28:1
   |
28 | #[thunderclap]
   | ^^^^^^^^^^^^^^ function or associated item not found in `clap::App<'_, '_>`

error: aborting due to previous error

Unwrapping Optional global parameter panics

This code

#![feature(proc_macro)]
extern crate thunder;
extern crate clap;

use thunder::thunderclap;

struct Loki;

#[thunderclap(example: String: "Error, here")]
impl Loki {
    fn hello() {
        println!("Hello, world!");
    }
}

fn main() {
    Loki::start();
}

will cause a program to panic when running the hello hook without a name, which should be optional!

This issue replaces #16

"Loki" example does not compile

The Loki example does not compile.

$ cargo run help
   Compiling test-thunder v0.1.0 (/home/xxx/tmp/test-thunder)
error: custom attribute panicked
 --> src/main.rs:9:1
  |
9 | #[thunderclap(example: Option<String>: "Error, here", another_example: String: "No error, here")]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = help: message: index out of bounds: the len is 1 but the index is 1

Running on edition = "2018":

$ rustc --version
rustc 1.33.0-nightly (adbfec229 2018-12-17)

Align param defs in attribute with Rust syntax

#[thunderclap(drunk: bool: "Thor drinks a lot", hammers: Option<u8>: "This isn't a joke about being drunk")]

hmmmm

#[thunderclap(drunk: bool = "Thor drinks a lot", hammers: Option<u8> = "This isn't a joke about being drunk")] [makes me more happy]

Doc comments are not picked up for subcommands without arguments

Given this code:

#[thunderclap]
impl Thor {
    /// Print a test message
    fn test(x: &str) {
        println!("Hello {}", x);
    }

    /// Start the daemon
    fn daemonize() {
        println!("Trying to daemonize...");
    }
}

the following --help is generated:

Thor 


USAGE:
    wgd [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    daemonize    
    help         Prints this message or the help of the given subcommand(s)
    test         Print a test message

Note the lack of a description for the daemonize subcommand. Notably, when a parameter is added, the description is picked up on

Rewrite proposal

Hello!
After talking about thunder with @spacekookie, she told me about a effort to rewrite thunder to have a better usability and code.

Thinking about that, I thought about proposing a new way to write thunder apps.
So far my proposal would make a simple hello world look like this:

#![feature(use_extern_macros)]

extern crate thunder_derive;
extern crate thunder;

#[derive(ThunderApp)]
struct Thor {
    /// Bla bla bl
    #[thunder(take_value = false)] // Default is to take value
    drunk: bool,

    /// What will be Thor's age today
    #[thunder(default_value = 1342)] // Can configure flag default value
    age: i32
}

#[thunderclap]
impl Thor {
    /// This is a subcommand, as before
    fn hello(&self, name: Option<&str>) {
        println!("Hello, {}! Nice to meet you, I'm Thor and I'm {} years old", name.unwrap_or("world"), self.age);
    }

    fn me(&self) {
        let drunk = if self.drunk {
            "drunk!"
        } else {
            "not drunk!"
        };

        println!("Huh, me? I'm Thor! And I'm {}");
    }
}

fn main() {
    Thor::start();
}

This is strongly inspired by structopt.
The main idea is to have global args parsing work like normal args do in structopt, and subcommands work as they work right now. Thus being more flexible, while still being fast to iterate.

I couldn't think about how to make subcommand arguments as flexible, but it's on my list of things to improve too

Thunder code stealing error messages from compiler

Hi, check this code out:

use thunder::thunderclap;
struct MyApp;
#[thunderclap]
impl MyApp {
    fn hello(name: &str) -> Result<&str,()> {
        println!("Hello {}", name);
    }
}
fn main() {
    MyApp::hello("kat");
}

Compilation errors:

$ cargo check 
    Checking test-thunder v0.1.0 (/home/xxx/tmp/test-thunder)
error[E0308]: mismatched types
 --> src/main.rs:5:1
  |
5 | #[thunderclap]
  | ^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
  |
  = note: expected type `std::result::Result<&str, ()>`
             found type `()`

error[E0308]: match arms have incompatible types
 --> src/main.rs:5:1
  |
5 | #[thunderclap]
  | ^^^^^^^^^^^^^^
  | |
  | expected enum `std::result::Result`, found ()
  | match arm with an incompatible type
  |
  = note: expected type `std::result::Result<&str, ()>`
             found type `()`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `test-thunder`.

I see two issues here:

  • thunderclap is "stealing" the error positioning, which is unfortunate because on large codebases it could make hard to understand where exactly is the error
  • There are two errors reported instead of one

Correct error expected:

$ cargo_check 
    Checking test-thunder v0.1.0 (/home/xxx/tmp/test-thunder)
error[E0308]: mismatched types
 --> src/main.rs:7:45
  |
7 |       fn hello(name: &str) -> Result<&str,()> {
  |  _____________________________________________^
8 | |         println!("Hello {}", name);
9 | |     }
  | |_____^ expected enum `std::result::Result`, found ()
  |
  = note: expected type `std::result::Result<&str, ()>`
             found type `()`

Running on edition = "2018":

$ rustc --version
rustc 1.33.0-nightly (adbfec229 2018-12-17)

Opinions?

Support global arguments

This means arguments not bound to a subcommand. The usage string for such an option would look as follows

tool [global options] <command> [local options]

This is analogue to how docopt allows you to handle options

Support argument type other than str

Trying to define subcommands such as the following fails:

#[thunderclap]
impl Thor {
    /// Print a test message
    fn test(x: &str) {
        println!("Hello {}", x);
    }

    /// Start the daemon
    fn daemonize(bar: u8) {
        println!("Trying to daemonize... (bar={})", bar);
    }
}

with this error:

error[E0308]: mismatched types
  --> src/main.rs:35:1
   |
35 | #[thunderclap]
   | ^^^^^^^^^^^^^^ expected u8, found &str
   |
   = note: expected type `u8`
              found type `&str`

It'd be nice if at least everything implementing From<&str> was supported, failing the program if the conversion fails

Examples are panicing

I have following toml

[dependencies]
clap = "2"
thunder = "0.3"

Code is Thor example.

Output:

   Compiling winapi v0.3.5
   Compiling sample_app v0.1.0 (file:///C:/Users/Alex/Documents/Repo/sample_app)
   Compiling atty v0.2.10
   Compiling clap v2.31.2
   Compiling thunder v0.3.1
error: custom attribute panicked
  --> src\main.rs:10:1
   |
10 | #[thunderclap(drunk: bool = "Bla bla bla")]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: message: index out of bounds: the len is 2 but the index is 2

error: aborting due to previous error

error: Could not compile `sample_app`.

To learn more, run the command again with --verbose.

Process finished with exit code 101

Unclear global variables usage (need examples)

Consider this simple snippet:

use thunder;
use clap;
use thunder::thunderclap;
struct MyApp;
#[thunderclap(param: String: "A global var")]
impl MyApp {
    /// Scan a directory
    fn scan(source_dir: String) {
        println!("param={}", param);
    }
}
fn main() {
    MyApp::start();
}

returns an error when running compiling:

$ cargo run 
   Compiling test-thunder v0.1.0 (/home/xxx/tmp/test-thunder)
error[E0425]: cannot find value `param` in this scope
 --> src/main.rs:8:1
  |
8 | #[thunderclap(param: String: "A global var")]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

or also

$ cargo run --param hey
error: Found argument '--param' which wasn't expected, or isn't valid in this context

USAGE:
    cargo run [OPTIONS] [--] [args]...

For more information try --help

How are global variable supposed to be used? Can you help with some more detailed examples?

thanks

Would nicer error messages be possible?

When i didn't provide a valid boolean, i got a not so nice error message:

thor bla aged
thread 'main' panicked at 'Failed to parse value. Double check!: ParseBoolError { _priv: () }', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Would it be possible to instead print something like:
Error: <drunk> needs to be "true" or "false"
or something similar?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.