1 unstable release
Uses new Rust 2024
new 0.1.0 | Apr 28, 2025 |
---|
#439 in Command-line interface
8KB
77 lines
pluribus
Small crate providing a macro to create multicall binaries declaratively.
lib.rs
:
pluribus
A small macro crate to make multicall binaries easier!
What is a multicall binary?
Multicall binaries are simply single executables that can behave as many different executables.
Good and famous examples of such a multicall binary would
be busybox
and uutils
.
What is included?
This crate provides a single macro, pluribus!()
,
with a special, easy to read and write DSL (special syntax) that
declaratively turns your modules into separate applications.
Hmm... not quite sure I understood...
Well, no biggie! That's what examples are for!
use pluribus::pluribus;
// Declaring a binary 'greet'.
mod greet {
// Start is our start symbol!
pub fn start(args: &[String]) {
for s in &args[1..] {
println!("Greetings, {s}!");
}
}
}
// Declaring a binary 'bye'
mod bye {
// Start is our start symbol!
pub fn start(args: &[String]) {
for s in &args[1..] {
println!("Goodbye, {s}!");
}
}
}
fn main() -> std::io::Result<()> {
// symbol: <our function that starts a binary, defaulting to main>;
// returning: <return type of the binaries>;
// with: <list of all modules we wish to turn into binaries>
pluribus!(
symbol: start;
returns: ();
with:
- greet;
- bye;
)
// skipping first argument because this is an example,
// which has always "pluribus" as the first argument.
(&std::env::args().skip(1).collect::<Vec<_>>());
Ok(())
}
This small program, let's call it 'test', now includes both the greet
and bye
binaries!
Now, how are they accessed? Like this:
> ./test greet Alice Bob
Greetings, Alice!
Greetings, Bob!
Or, alternatively, we can create a symlink or rename the binary:
> ln -s test greet
> ./greet Alice Bob
Greetings, Alice!
Greetings, Bob!
The syntax
Admittedly, it is a little bit dumb and too strict, but because it is so simple, it should prove easy to use.
There are three directives in the language, and they must be stated in order.
They are as follows:
symbol
symbol
specifies the main symbol of the sub-binary, eg. main
, _start
.
symbol: main;
It defaults to main
. If you are using main
as the symbol, you may omit this.
returns
returns
specifies the return type of the sub-binary, eg ()
, std::io::Result<()>
.
returns: ();
It defaults to ()
. If you are using ()
as the return type, you may omit this.
with
with
specifies the beginning of the list of modules/sub-binaries. It must be the
last (or only) directive.
with:
- bin1;
- bin2;
- bin3;