treesap
A #[derive(Parser)] interface for sap
treesap is a companion crate to sap that lets
you declare your CLI arguments as a plain Rust struct instead of writing a
manual parsing loop. Annotate your struct with #[derive(Parser)] and treesap
generates a parse() method that calls into sap under the hood.
treesap is a work in progress. See the Status section for a precise breakdown of what is implemented today versus what is planned. For production-grade argument parsing, consider using sap directly until treesap reaches a stable feature set.
Status
| Feature | Status |
|---|---|
#[derive(Parser)] on structs |
Implemented |
bool fields as long flags |
Implemented |
Short flag support (-v) |
Planned |
Value-taking fields (String, u32, …) |
Planned |
Option<T> fields (optional arguments) |
Planned |
| Required vs optional field distinction | Planned |
--help auto-generation |
Planned |
--version auto-generation |
Planned |
| Subcommands | Planned |
Installation
Add both sap and treesap to your Cargo.toml:
[]
= "0.2.0"
= "0.1.0"
Quick Start
Declare your arguments as a struct and derive Parser. Each bool field
becomes a long flag whose name matches the field name exactly:
use Parser;
Running the program:
$ myprogram --verbose
verbose mode enabled
$ myprogram --verbose --dry-run
verbose mode enabled
dry-run: no changes will be made
What parse() does
The generated parse() method:
- Calls
sap::Parser::from_env()to readstd::env::args(). - Iterates over all arguments with
forward(). - Matches each
Argument::Long(name)against the field names in the struct. - Returns
Errfor any unrecognised argument viasap::Argument::unexpected(). - Returns
Ok(Self { … })once all arguments are consumed.
Because parse() is generated by a proc-macro, the struct must be defined in a
context where sap is also a direct dependency of your crate.
Current limitations
- Only
boolfields are supported. Any other field type will compile but produce incorrect behaviour (all fields are hardcoded totruewhen their flag appears). #[arg(…)]and#[command(…)]attributes are accepted by the macro but not yet acted upon; short flags, custom flag names, and descriptions are silently ignored.- Fields are initialised with
.unwrap(), so a missing flag causes a panic rather than a clean error. Make all fields optional by providing defaults until required-field handling is implemented. - Enums and unions are not supported (
todo!()will panic at compile time).
Relationship to sap
treesap is a thin layer on top of sap. The
generated parse() function is equivalent to what you would write by hand using
sap::Parser. If treesap does not yet support a feature you need, you can drop
down to sap directly:
use ;
See the sap README and sap documentation for the full API reference.
License
This project is licensed under the Apache-2.0 License. For more information, please see the LICENSE file.