12 个稳定版本
2.0.5 | 2022 年 12 月 28 日 |
---|---|
2.0.4 | 2022 年 11 月 11 日 |
2.0.3 | 2022 年 10 月 30 日 |
1.0.22 | 2022 年 9 月 22 日 |
0.1.0 | 2022 年 8 月 9 日 |
#172 在 命令行界面
43KB
471 行
爬升
爬升是一个用于创建 CLI 应用程序的简单 Rust crate。允许创建接受输入、选项和可选输入的命令。爬升处理所有输入参数验证和解析,并保证只有正确数量的输入和有效选项传递到您的命令中。爬升还将生成您应用程序和命令的帮助菜单。
爬升遵循创建应用程序的 建造者模式。
示例应用程序 - 计算器
创建应用程序
假设您想创建一个简单的计算器应用程序,包含两个命令
add
- 接收两个数字,将它们相加,并返回结果div
- 接收两个数字,将它们相除,并返回结果
在您的 main.rs
文件中,首先使用 create_app
宏创建一个基本的 Climb 应用程序
use climb::*;
fn main() {
let calc_app = create_app!();
let _ = calc_app.run();
}
调用 run
函数以使用命令行参数运行您的应用程序。现在不要担心这个函数的返回值。create_app
宏将创建一个默认应用程序,其名称、描述和版本从您的 crate 的 cargo.toml 文件中获取。
如果您想更改这些值,您可以使用
let mut calc_app = create_app!();
calc_app = calc_app.name("cool_calc");
calc_app = calc_app.desc("This app does some cool math");
calc_app = calc_app.version("1.0.0");
或者链式命令以使其更易于阅读
let _ = create_app!()
.name("cool_calc")
.desc("This app does some cool math")
.version("1.0.0")
.run();
如果您现在运行我们的代码,您将得到以下结果
$ cool_calc
This app does some cool math
USAGE:
cool_calc [OPTIONS] [COMMAND]
OPTIONS:
-h, --help Print help information
-v, --version Print version
COMMANDS:
Run `cool_calc [COMMAND] --help` to see help information for a specific command
爬升创建了一个应用程序并添加了一些默认选项:help
和 version
。要向应用程序添加更多功能,您需要使用 Climb 命令。
使用命令添加功能
要向应用程序添加两个命令,您可以使用 app::command
API。当您调用 app::command
函数时,您必须传递一个命令结构。您可以使用 Command::new
let _ = create_app!()
.name("cool_calc")
.desc("This app does some cool math")
.version("1.0.0")
.command(
Command::new(
"add",
"Add two numbers",
add_fn
)
.arg("number_a")
.arg("number_b")
)
.command(
Command::new(
"div",
"Divide two numbers",
div_fn
)
.arg("number_a")
.arg("number_b")
.option(
CommandOption::new(
"round",
"Round the result"
)
)
)
.run();
命令::new
函数接受命令名称和描述作为参数。它还接受一个在执行命令时将被调用的函数。我们尚未为这些函数创建定义;下一节将描述如何创建这些函数。
我们还在使用Command
API向命令添加参数和选项。我们为每个命令添加了两个参数:number_a
和number_b
。这两个数字将是命令要操作的两个数字。我们还向div
命令添加了一个选项:round
。如果添加此选项,则命令应返回一个四舍五入的结果。
在 climb 命令中创建和使用函数
要将add
和div
命令添加到计算器应用程序中,您需要创建这些命令实际执行的函数。在这些函数中,您可以放置命令的逻辑。
爬升函数遵循CommandFunction
签名。它看起来像这样
type CommandFunction = fn(FunctionInput, FunctionOptions) -> FunctionResult;
参数和返回类型如下定义
type FunctionInput = Vec<String>;
type FunctionOptions = Vec<FunctionOption>;
type FunctionResult = Result<Option<String>, String>;
这可能看起来有些吓人,但实际上非常简单。FunctionInput
存储我们函数的输入(这些被称为参数),FunctionOptions
存储我们的命令接受的任何选项。选项也可以有参数。FunctionResult
是所有Climb命令必须返回的标准结果类型。运行您的函数的结果始终从之前使用的App::run()
命令返回。
让我们从创建add
命令的函数开始。Climb函数保证将正确数量的参数传递给它们,因此您可以安全地假设有2个参数传递进来。如果您为您的命令添加了任何选项,只有这些有效的选项才能传递到您的函数中
fn add_fn(input: FunctionInput, _: FunctionOptions) -> FunctionResult {
let num_a: i32 = input.get(0).unwrap().parse().unwrap();
let num_b: i32 = input.get(1).unwrap().parse().unwrap();
let result = num_a + num_b;
println!("{}", result);
Ok(None)
}
我们首先展开两个输入,并将它们转换为整数。然后相加并打印结果。您可以从函数中返回结果,封装为Ok(Some(<result>))
,但我们将只返回Ok(None)
,并从函数内部打印结果。
对于div
函数
fn div_fn(input: FunctionInput, options: FunctionOptions) -> FunctionResult {
let num_a: f32 = input.get(0).unwrap().parse().unwrap();
let num_b: f32 = input.get(1).unwrap().parse().unwrap();
let mut result = num_a / num_b;
if options.contains(&FunctionOption(String::from("--round"), None)) {
result = result.round();
}
println!("{}", result);
Ok(None)
}
就像之前一样,我们可以展开前两个输入。除法结果存储在result
变量中,并打印到控制台。我们还检查是否将--round
选项传递到命令中,如果是,则将结果四舍五入。有几种不同的方法可以做到这一点,但这只是其中一种示例。
使用应用程序
如果您现在不带参数运行应用程序,这是您将得到的结果
$ cool_calc
This app does some cool math
USAGE:
cool_calc [OPTIONS] [COMMAND]
OPTIONS:
-h, --help Print help information
-v, --version Print version
COMMANDS:
add Add two numbers
div Divide two numbers
Run `cool_calc [COMMAND] --help` to see help information for a specific command
那里列出了两个命令:add
和div
。您可以尝试运行以下命令:div --help
,以查看仅针对div
命令的帮助菜单
$ cool_calc div --help
Divide two numbers
USAGE:
cool_calc div [OPTIONS] <NUMBER_A> <NUMBER_B>
ARGS:
<NUMBER_A>
<NUMBER_B>
OPTIONS:
-h, --help Print help information
--round Round the result
最后,我们可以运行命令以测试它们是否正常工作
$ cool_calc add 45 22
67
$ cool_calc div 45 22
2.0454545
$ cool_calc div --round 45 22
2
依赖项
~0–10MB
~55K SLoC