2022-12-25 22:27:17 -05:00
|
|
|
Contents
|
|
|
|
========
|
2022-12-25 22:30:46 -05:00
|
|
|
* [Licensing](#licensing)
|
2022-12-25 22:27:17 -05:00
|
|
|
* [The **Cmd** trait](#the-cmd-trait)
|
|
|
|
* [A simple example applet](#a-simple-example-applet)
|
|
|
|
* [Incorporating a new applet](#incorporating-a-new-applet)
|
|
|
|
|
2022-12-25 22:30:46 -05:00
|
|
|
## Licensing
|
|
|
|
This code is BeerWare. It is essentially in the public domain. If you wish to
|
|
|
|
contribute, your name may be added to the credits, but by contributing you agree
|
|
|
|
to basically place your contributions into the public domain.
|
|
|
|
|
2022-12-25 22:27:17 -05:00
|
|
|
## The Cmd trait
|
|
|
|
The `Cmd` trait is defined in `src/cmd/mod.rs`. All applets should live in their
|
|
|
|
own submodule under `crate::cmd` and include a struct with the name of the command,
|
|
|
|
in snake case. This struct must implement `Cmd`. It is recommended that this struct
|
|
|
|
have at least the fields `name: &'static str` and `path: crate::Path`. The
|
|
|
|
trait methods `name` and `path` can then just return the corresponding fields.
|
|
|
|
|
2023-01-06 23:53:41 -05:00
|
|
|
The applet module should further implement `Default` for the struct which implements
|
|
|
|
the `Cmd` trait.
|
2022-12-25 22:27:17 -05:00
|
|
|
|
|
|
|
## A Simple Example Applet
|
|
|
|
```Rust
|
|
|
|
// src/cmd/myapplet/mod.rs
|
|
|
|
use clap::Command;
|
|
|
|
use super::Cmd;
|
|
|
|
|
2023-01-06 23:53:41 -05:00
|
|
|
#[derive(Debug)]
|
2022-12-25 22:27:17 -05:00
|
|
|
pub struct MyApplet {
|
|
|
|
name: &'static str,
|
|
|
|
path: crate::Path,
|
|
|
|
}
|
|
|
|
|
2023-01-06 23:53:41 -05:00
|
|
|
impl Default for MyApplet {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
name: "myapplet",
|
|
|
|
path: Some(crate::Path::UseBin),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-12-25 22:27:17 -05:00
|
|
|
|
|
|
|
impl Cmd for MyApplet {
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
self.name
|
|
|
|
}
|
|
|
|
|
|
|
|
fn cli(&self) -> clap::Command {
|
|
|
|
Command::new(self.name)
|
|
|
|
.version(env!("CARGO_PKG_VERSION"))
|
|
|
|
.author("Zaphod Beeblebrox")
|
|
|
|
.about("Does sketchy things")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run(&self, _matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
|
|
|
println!("If there's anything more important than my ego around, I want it caught and shot now.");
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn path(&self) -> Option<crate::Path> {
|
|
|
|
self.path
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
## Incorporating a new applet
|
|
|
|
Each command module should be public in `src/cmd/mod.rs` and both the struct which
|
2023-01-06 23:53:41 -05:00
|
|
|
implements `Cmd` should be exported as public in that file. The function `cmd::get`
|
|
|
|
has a match statement, to which should be added a line which matches the name of
|
|
|
|
the new command and returns an `Option<Box<dyn Cmd>>` for your type. The static
|
|
|
|
`cmd::COMMANDS` should have your new command's name added and the array's number
|
|
|
|
incremented by 1.
|
2022-12-25 22:27:17 -05:00
|
|
|
|