https://github.com/vidhanio/fncli
An attribute macro to simplify writing simple command line applications.
https://github.com/vidhanio/fncli
command-line macro rust
Last synced: 9 months ago
JSON representation
An attribute macro to simplify writing simple command line applications.
- Host: GitHub
- URL: https://github.com/vidhanio/fncli
- Owner: vidhanio
- License: apache-2.0
- Created: 2022-11-28T19:56:47.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2023-03-22T23:38:26.000Z (almost 3 years ago)
- Last Synced: 2024-09-15T07:10:33.030Z (over 1 year ago)
- Topics: command-line, macro, rust
- Language: Rust
- Homepage: https://crates.io/crates/fncli
- Size: 39.1 KB
- Stars: 34
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# `fncli`
An attribute macro to simplify writing simple command line applications.
## Example
```rust
#[fncli::cli]
fn main(a: i32, b: i32) {
println!("{}", a + b);
}
```
```rust
$ cargo run 1 2
3
```
```rust
$ cargo run 1
missing argument: `b: i32`
USAGE:
target/debug/examples/add
```
```rust
$ cargo run 1 2 3
too many arguments (expected 2)
USAGE:
target/debug/examples/add
```
```rust
$ cargo run 1 a
failed to parse argument: `b: i32`: ParseIntError { kind: InvalidDigit }
USAGE:
target/debug/examples/add
```
For a more complete example, see [the time elapsed example](examples/time_elapsed.rs).
## How It Works
```rust
fn main() {
let (a, b) = {
let mut args = std::env::args();
let cmd = args.next().expect("should have a command name");
let exit = |err: &str| -> ! {
eprintln!("{err}");
eprintln!();
eprintln!("USAGE:\n\t{cmd} ");
std::process::exit(1)
};
let tuple = (
i32::from_str(
&args
.next()
.unwrap_or_else(|| exit("missing argument: `a: i32`")),
)
.unwrap_or_else(|e| exit(&format!("failed to parse argument `a: i32` ({e:?})"))),
i32::from_str(
&args
.next()
.unwrap_or_else(|| exit("missing argument: `b: i32`")),
)
.unwrap_or_else(|e| exit(&format!("failed to parse argument `b: i32` ({e:?})"))),
);
if args.next().is_some() {
exit("too many arguments (expected 2)");
}
tuple
};
{
println!("{}", a + b);
}
}
```
The generated code is very simple, and not too different from how one would write the code by hand.