Crates.io | palc |
lib.rs | palc |
version | 0.0.2 |
created_at | 2025-06-17 11:38:04.693974+00 |
updated_at | 2025-09-16 05:46:54.498357+00 |
description | WIP: Command Line Argument Parser with several opposite design goal from Clap |
homepage | |
repository | https://github.com/oxalica/palc |
max_upload_size | |
id | 1715577 |
size | 152,899 |
Prototype of a command line argument parser with several opposite design goals from clap.
⚠️ This project is in alpha stage and is not ready for production yet. The API is subject to change. Feedbacks are welcome.
Check ./test-suite/src/bin/*-palc.rs
for example usages.
palc is an un-opinionated2 derive-based argument parser.
We choose to align with the clap 4.0 derive API: Parser
, Args
and Subcommand
macros with almost compatible command(..)
and arg(..)
attributes.
In most cases, switching between clap derive and palc derive is as easy as
changing a line in Cargo.toml
and relevant use
statements. No vendor locking.
Writing your CLI structs first before deciding which crate to use.
palc also aim to provide a decent CLI experience under default features:
help generations, non-UTF-8 support, argument constraints, Args
composition,
subcommands, you name it.
Though some of clap features are not-yet-implemented.
Argument behaviors:
Boolean flags --verbose
.
Named arguments --long value
, -svalue
-czf
--long=v
-f=v
. Unnamed/free/positional arguments FILE
.
--
.arg(trailing_var_arg)
).--
(arg(last)
). Counting number of occurrence (ArgAction::Count
).
Custom ArgAction.
Custom number of values (arg(num_args)
).
Overrides.
List of magic argument types with automatic default behaviors:
T where T: TryFrom<&OsStr> || TryFrom<&str> || FromStr
(named & unnamed)bool
(named)Option<T>
(named)Option<Option<T>>
(named)
FIXME: The semantic disagrees with clap yet.Vec<T>
(named & unnamed)Option<Vec<T>>
(named & unnamed)Vec<Vec<T>>
Option<Vec<Vec<T>>>
Default values. (arg(default_value_t)
)
arg(default_value)
)
arg(default_value_t)
if possible.Argument value parsing:
derive(ValueEnum)
value(rename_all)
value(name)
value(skip)
value(help)
PathBuf
, OsString
.From<OsString>
, From<String>
or FromStr
.arg(ignore_case)
ValueEnum
that has no UPPERCASE variants are supported yet, due to implementation limitation.Argument validations:
Composition:
arg(flatten)
.
Help generation.
Note: Help text is only for human consumption. The precise format is unstable,
may change at any time and is not expected to exactly follow clap
's help format
(although that is our general direction).
--help
.-h
.--version
.arg(default_value{,_t})
.Helpful error messages.
Term features:
Reflection.
Completions.
derive
macros, staticallyThe only way to define a CLI parser in palc is via derive
-macros. It is not
possible to manually write impl
or even construct it dynamically.
Argument parsers are prepared, validated and generated during compile time.
The runtime does nothing other than parsing, thus has no startup overhead.
Also no insta-panics at runtime!
On the contrary, clap only works on builder API under the hood and its derive API translates attributes to its builder API. The parser is still composed, verified, and then executed at runtime. This suffers from startup time penalty.
This implies we do more work in proc-macro while rustc does less work on generated code. In compilation time benchmarks, we outperform clap-derive in both full build and incremental build.
Despite how many features we have, we keep binary overhead in check. Our goal is to give a size overhead that deserves its features, without unreasonable or meaningless bloat.
Unlike other min-size-centric projects, eg. pico-args or gumdrop, we choose NOT to sacrifice CLI user experience, or force CLI designers to write more (repetitive) code. We are striving for a good balance between features and their cost.
In the benchmarks (./bench.txt
), binary size of small-to-medium
CLI structs using palc
is comparable to and sometimes smaller than argh
.
The derive interface is inspired and mimicking clap
's derive interface.
The palc runtime design is inspired by miniserde
.
Due to design differences, some attributes cannot be implemented statically or require a different syntax. TODO: Document all attributes and notable differences with clap. ↩
argh say they are "opinionated" as an excuse of subjective and "creative" choice on derive attribute names and letter case restrictions. We are against these. ↩