当前位置: 首页 > news >正文

做网站推广广告韩国小清新网站模板

做网站推广广告,韩国小清新网站模板,手机端网站整站下载,wap网站 劣势系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学 Rust 编程】六、枚举和模式匹配 【跟小嘉学 Rust 编程】七、使用包(Packages)、单元包(Crates)和模块(Module)来管理项目 【跟小嘉学 Rust 编程】八、常见的集合 【跟小嘉学 Rust 编程】九、错误处理(Error Handling) 【跟小嘉学 Rust 编程】十一、编写自动化测试 【跟小嘉学 Rust 编程】十二、构建一个命令行程序 【跟小嘉学 Rust 编程】十三、函数式语言特性迭代器和闭包 【跟小嘉学 Rust 编程】十四、关于 Cargo 和 Crates.io 【跟小嘉学 Rust 编程】十五、智能指针(Smart Point) 【跟小嘉学 Rust 编程】十六、无畏并发(Fearless Concurrency) 【跟小嘉学 Rust 编程】十七、面向对象语言特性 【跟小嘉学 Rust 编程】十八、模式匹配(Patterns and Matching) 【跟小嘉学 Rust 编程】十九、高级特性 【跟小嘉学 Rust 编程】二十、进阶扩展 【跟小嘉学 Rust 编程】二十一、网络编程 【跟小嘉学 Rust 编程】二十三、Cargo 使用指南 【跟小嘉学 Rust 编程】二十四、内联汇编(inline assembly) 【跟小嘉学 Rust 编程】二十五、Rust命令行参数解析库(clap) 文章目录 系列文章目录[TOC](文章目录) 前言一、 Clap 使用方式一build构建1.1、引入 clap 库1.2、快速启动1.3、配置解析器(Configuring the Parser)1.3.1、使用 Command 构建解析器1.3.2、使用 command! 构建解析器1.3.2、使用 Command::next_line_help 方法 1.4、添加命令行参数(Adding Arguments)1.4、设置参数行为1.5、参数选项1.5.1、参数选项1.5.2、开启/关闭标志1.5.3、参数调用计数1.5.4、默认值1.5.5、参数校验1.5.5.1、默认情况1.5.5.2、枚举值(Enumerated values)1.5.5.3、校验值(Validated values)1.5.5.4、自定义解析器(Custom Parser)1.5.5.5、参数关系(Argument Relations)1.5.5.6、自定义校验(Custom Validation) 1.6、子命令(Subcommand)1.7、测试 二、 Clap 使用方式二derive feature2.1、添加依赖2.2、快速开始2.3、配置解析器2.3.1、配置解析器2.3.2、默认值2.3.3、Command::next_line_help 替代 2.4、添加参数2.4.1、添加可选参数2.4.2、添加多值参数2.4.3、参数选项2.4.3.1、短参数名称和长参数名称2.4.3.2、开启和关闭2.4.3.3、参数计数2.4.3.4、参数默认值2.4.3.5、参数枚举2.4.3.6、参数校验2.4.3.7、自定义解析2.4.3.8、参数关系2.4.3.9、自定义校验 2.5、子命令 三、如何选择总结 前言 本章节内容讲解 Rust 的第三方库 Clap这是一个命令行参数解析库。使用API创建解析的方式有两种Derive 方式、Builder方式。 主要教材参考 《The Rust Programming Language》 主要教材参考 《Rust For Rustaceans》 主要教材参考 《The Rustonomicon》 主要教材参考 《Rust 高级编程》 主要教材参考 《Cargo 指南》 一、 Clap 使用方式一build构建 1.1、引入 clap 库 cargo add clap -- features cargo需要注意如果不启用 cargo feature 则会报如下错误。 requires cargo feature1.2、快速启动 //main.rs use std::path::PathBuf;use clap::{arg, command, value_parser, ArgAction, Command};fn main() {let matches command!() // requires cargo feature.arg(arg!([name] Optional name to operate on)).arg(arg!(-c --config FILE Sets a custom config file)// We dont have syntax yet for optional options, so manually calling required.required(false).value_parser(value_parser!(PathBuf)),).arg(arg!(-d --debug ... Turn debugging information on)).subcommand(Command::new(test).about(does testing things).arg(arg!(-l --list lists test values).action(ArgAction::SetTrue)),).get_matches();// You can check the value provided by positional arguments, or option argumentsif let Some(name) matches.get_one::String(name) {println!(Value for name: {name});}if let Some(config_path) matches.get_one::PathBuf(config) {println!(Value for config: {}, config_path.display());}// You can see how many times a particular flag or argument occurred// Note, only flags can have multiple occurrencesmatch matches.get_one::u8(debug).expect(Counts are defaulted){0 println!(Debug mode is off),1 println!(Debug mode is kind of on),2 println!(Debug mode is on),_ println!(Dont be crazy),}// You can check for the existence of subcommands, and if found use their// matches just as you would the top level cmdif let Some(matches) matches.subcommand_matches(test) {// $ myapp test was runif matches.get_flag(list) {// $ myapp test -l was runprintln!(Printing testing lists...);} else {println!(Not printing testing lists...);}}// Continued program logic goes here... }1、默认执行情况 cargo run Debug mode is off2、参看帮助文档 cargo run --help Run a binary or example of the local packageUsage: cargo run [OPTIONS] [args]...Arguments:[args]... Arguments for the binary or example to runOptions:-q, --quiet Do not print cargo log messages--bin [NAME] Name of the bin target to run--example [NAME] Name of the example target to run-p, --package [SPEC] Package with the target to run-j, --jobs N Number of parallel jobs, defaults to # of CPUs.--keep-going Do not abort the build as soon as there is an error (unstable)-r, --release Build artifacts in release mode, with optimizations--profile PROFILE-NAME Build artifacts with the specified profile-F, --features FEATURES Space or comma separated list of features to activate--all-features Activate all available features--no-default-features Do not activate the default feature--target TRIPLE Build for the target triple--target-dir DIRECTORY Directory for all generated artifacts--manifest-path PATH Path to Cargo.toml--message-format FMT Error format--unit-graph Output build graph in JSON (unstable)--ignore-rust-version Ignore rust-version specification in packages--timings[FMTS] Timing output formats (unstable) (comma separated): html, json-h, --help Print help-v, --verbose... Use verbose output (-vv very verbose/build.rs output)--color WHEN Coloring: auto, always, never--frozen Require Cargo.lock and cache are up to date--locked Require Cargo.lock is up to date--offline Run without accessing the network--config KEYVALUE Override a configuration value-Z FLAG Unstable (nightly-only) flags to Cargo, see cargo -Z help for detailsRun cargo help run for more detailed information.3、使用 -dd 参数 cargo run -- -dd test Debug mode is on Not printing testing lists...1.3、配置解析器(Configuring the Parser) 1.3.1、使用 Command 构建解析器 你可以使用 Command 开始构建一个解析器。 use clap::{arg, Command};fn main() {let matches Command::new(MyApp).version(1.0).author(Kevin K. kbknappgmail.com).about(Does awesome things).arg(arg!(--two VALUE).required(true)).arg(arg!(--one VALUE).required(true)).get_matches();println!(two: {:?},matches.get_one::String(two).expect(required));println!(one: {:?},matches.get_one::String(one).expect(required)); }1、查看帮助文档 cargo run -- --helpDoes awesome thingsUsage: hello_world --two VALUE --one VALUEOptions:--two VALUE --one VALUE -h, --help Print help-V, --version Print version1.3.2、使用 command! 构建解析器 你也可以使用 command! 宏 构建解析器不过要想使用 command! 宏你需要开启 cargo feature。 use clap::{arg, command};fn main() {// requires cargo feature, reading name, version, author, and description from Cargo.tomllet matches command!().arg(arg!(--two VALUE).required(true)).arg(arg!(--one VALUE).required(true)).get_matches();println!(two: {:?},matches.get_one::String(two).expect(required));println!(one: {:?},matches.get_one::String(one).expect(required)); }1、查看帮助文档 cargo run -- --helpUsage: hello_world --two VALUE --one VALUEOptions:--two VALUE --one VALUE -h, --help Print help-V, --version Print version1.3.2、使用 Command::next_line_help 方法 使用 Command::next_line_help 方法 可以修改参数打印行为 use clap::{arg, command, ArgAction};fn main() {let matches command!() // requires cargo feature.next_line_help(true).arg(arg!(--two VALUE).required(true).action(ArgAction::Set)).arg(arg!(--one VALUE).required(true).action(ArgAction::Set)).get_matches();println!(two: {:?},matches.get_one::String(two).expect(required));println!(one: {:?},matches.get_one::String(one).expect(required)); }1、显示帮助文档 cargo run -- --helpUsage: hello_world --two VALUE --one VALUEOptions:--two VALUE--one VALUE-h, --helpPrint help-V, --versionPrint version效果就是参数的描述和参数是分行的描述信息在参数下一行。 1.4、添加命令行参数(Adding Arguments) 我们可以使用 Command::arg 方法来添加 Arg 对象来添加命令行参数 use clap::{command, Arg};fn main() {let matches command!() // requires cargo feature.arg(Arg::new(name)).get_matches();println!(name: {:?}, matches.get_one::String(name)); }1、查看帮助文档 cargo run -- --helpUsage: hello_world [name]Arguments:[name] Options:-h, --help Print help-V, --version Print version2、使用 name 参数默认 cargo run name: None3、使用 name 参数blob cargo run bob name: Some(bob)1.4、设置参数行为 需要注意参数默认值是一个 Set 类型 我们可以使用 Command::action 方法来设置 参数行为。如果可以添加多个只我们可以使用 ArgAction::Append use clap::{command, Arg, ArgAction};fn main() {let matches command!() // requires cargo feature.arg(Arg::new(name).action(ArgAction::Append)).get_matches();let args matches.get_many::String(name).unwrap_or_default().map(|v| v.as_str()).collect::Vec_();println!(names: {:?}, args); }1.5、参数选项 1.5.1、参数选项 一个参数行为的标志 顺序无关可选参数意图清晰 use clap::{command, Arg};fn main() {let matches command!() // requires cargo feature.arg(Arg::new(name).short(n).long(name)).get_matches();println!(name: {:?}, matches.get_one::String(name)); }上述代码我们定义了一个name参数缩写是n全拼是name也就是如下形式 -n, --name name我们使用方式就有如下几种 cargo run -- --name blo cargo run -- --nameblob cargo run -- -n blob cargo run -- -nblob cargo run -- -nblob 1.5.2、开启/关闭标志 我们可以是 ArgAction::SetTrue 开启参数 use clap::{command, Arg, ArgAction};fn main() {let matches command!() // requires cargo feature.arg(Arg::new(verbose).short(v).long(verbose).action(ArgAction::SetTrue),).get_matches();println!(verbose: {:?}, matches.get_flag(verbose)); } 1.5.3、参数调用计数 我们可以使用 ArgAction::Count use clap::{command, Arg, ArgAction};fn main() {let matches command!() // requires cargo feature.arg(Arg::new(verbose).short(v).long(verbose).action(ArgAction::Count),).get_matches();println!(verbose: {:?}, matches.get_count(verbose)); }默认值是0多次使用参数就会计数 1.5.4、默认值 我们前面设置的参数都是必选的但是也可以使用可选的如果是可选的我们可以使用 Option 并且可以使用 unwrap_or 方法也可以使用 Arg::default_value 方法设置默认值。 use clap::{arg, command, value_parser};fn main() {let matches command!() // requires cargo feature.arg(arg!([PORT]).value_parser(value_parser!(u16)).default_value(2023),).get_matches();println!(port: {:?},matches.get_one::u16(PORT).expect(default ensures there is always a value)); }1.5.5、参数校验 1.5.5.1、默认情况 默认情况下参数被认为是 String并且使用 UTF-8 校验。 1.5.5.2、枚举值(Enumerated values) 如果你的参数有多个特定的值我们可以使用 PossibleValuesParser 解析器 或者使用 Arg::value_parser([“val1”, …]) 进行设置。 use clap::{arg, command};fn main() {let matches command!() // requires cargo feature.arg(arg!(MODE).help(What mode to run the program in).value_parser([fast, slow]),).get_matches();// Note, its safe to call unwrap() because the arg is requiredmatch matches.get_one::String(MODE).expect(MODE is required and parsing will fail if its missing).as_str(){fast {println!(Hare);}slow {println!(Tortoise);}_ unreachable!(),} }如果我们开启了 derive feature 则我们也可以实现 ValueEnum 特征实现相同的功能 use clap::{arg, builder::PossibleValue, command, value_parser, ValueEnum};#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] enum Mode {Fast,Slow, }// Can also be derived with feature flag derive impl ValueEnum for Mode {fn value_variantsa() - a [Self] {[Mode::Fast, Mode::Slow]}fn to_possible_valuea(self) - OptionPossibleValue {Some(match self {Mode::Fast PossibleValue::new(fast).help(Run swiftly),Mode::Slow PossibleValue::new(slow).help(Crawl slowly but steadily),})} }impl std::fmt::Display for Mode {fn fmt(self, f: mut std::fmt::Formatter_) - std::fmt::Result {self.to_possible_value().expect(no values are skipped).get_name().fmt(f)} }impl std::str::FromStr for Mode {type Err String;fn from_str(s: str) - ResultSelf, Self::Err {for variant in Self::value_variants() {if variant.to_possible_value().unwrap().matches(s, false) {return Ok(*variant);}}Err(format!(invalid variant: {s}))} }fn main() {let matches command!() // requires cargo feature.arg(arg!(MODE).help(What mode to run the program in).value_parser(value_parser!(Mode)),).get_matches();// Note, its safe to call unwrap() because the arg is requiredmatch matches.get_one::Mode(MODE).expect(MODE is required and parsing will fail if its missing){Mode::Fast {println!(Hare);}Mode::Slow {println!(Tortoise);}} }1.5.5.3、校验值(Validated values) 我们可以使用 Arg::value_parser 验证并解析成我们需要的任何类型。 use clap::{arg, command, value_parser};fn main() {let matches command!() // requires cargo feature.arg(arg!(PORT).help(Network port to use).value_parser(value_parser!(u16).range(1..)),).get_matches();// Note, its safe to call unwrap() because the arg is requiredlet port: u16 *matches.get_one::u16(PORT).expect(PORT is required and parsing will fail if its missing);println!(PORT {port}); }1.5.5.4、自定义解析器(Custom Parser) 我们也可以使用自定义解析器用于改进错误信息提示和额外的验证。 use std::ops::RangeInclusive;use clap::{arg, command};fn main() {let matches command!() // requires cargo feature.arg(arg!(PORT).help(Network port to use).value_parser(port_in_range),).get_matches();// Note, its safe to call unwrap() because the arg is requiredlet port: u16 *matches.get_one::u16(PORT).expect(PORT is required and parsing will fail if its missing);println!(PORT {port}); }const PORT_RANGE: RangeInclusiveusize 1..65535;fn port_in_range(s: str) - Resultu16, String {let port: usize s.parse().map_err(|_| format!({s} isnt a port number))?;if PORT_RANGE.contains(port) {Ok(port as u16)} else {Err(format!(port not in range {}-{},PORT_RANGE.start(),PORT_RANGE.end()))} } 1.5.5.5、参数关系(Argument Relations) 我们可以声明 Arg 和 ArgGroup。ArgGroup 用于声明参数关系。 use std::path::PathBuf;use clap::{arg, command, value_parser, ArgAction, ArgGroup};fn main() {// Create application like normallet matches command!() // requires cargo feature// Add the version arguments.arg(arg!(--set-ver VER set version manually)).arg(arg!(--major auto inc major).action(ArgAction::SetTrue)).arg(arg!(--minor auto inc minor).action(ArgAction::SetTrue)).arg(arg!(--patch auto inc patch).action(ArgAction::SetTrue))// Create a group, make it required, and add the above arguments.group(ArgGroup::new(vers).required(true).args([set-ver, major, minor, patch]),)// Arguments can also be added to a group individually, these two arguments// are part of the input group which is not required.arg(arg!([INPUT_FILE] some regular input).value_parser(value_parser!(PathBuf)).group(input),).arg(arg!(--spec-in SPEC_IN some special input argument).value_parser(value_parser!(PathBuf)).group(input),)// Now lets assume we have a -c [config] argument which requires one of// (but **not** both) the input arguments.arg(arg!(config: -c CONFIG).value_parser(value_parser!(PathBuf)).requires(input),).get_matches();// Lets assume the old version 1.2.3let mut major 1;let mut minor 2;let mut patch 3;// See if --set-ver was used to set the version manuallylet version if let Some(ver) matches.get_one::String(set-ver) {ver.to_owned()} else {// Increment the one requested (in a real program, wed reset the lower numbers)let (maj, min, pat) (matches.get_flag(major),matches.get_flag(minor),matches.get_flag(patch),);match (maj, min, pat) {(true, _, _) major 1,(_, true, _) minor 1,(_, _, true) patch 1,_ unreachable!(),};format!({major}.{minor}.{patch})};println!(Version: {version});// Check for usage of -cif matches.contains_id(config) {let input matches.get_one::PathBuf(INPUT_FILE).unwrap_or_else(|| matches.get_one::PathBuf(spec-in).unwrap()).display();println!(Doing work using input {} and config {},input,matches.get_one::PathBuf(config).unwrap().display());} }此时 --set-ver VER|--major|--minor|--patch 是一个组的参数。 1.5.5.6、自定义校验(Custom Validation) 我们可以创建自定义校验错误 Command::error 方法可以返回指定错误 Error和自定义错误信息 use std::path::PathBuf;use clap::error::ErrorKind; use clap::{arg, command, value_parser, ArgAction};fn main() {// Create application like normallet mut cmd command!() // requires cargo feature// Add the version arguments.arg(arg!(--set-ver VER set version manually)).arg(arg!(--major auto inc major).action(ArgAction::SetTrue)).arg(arg!(--minor auto inc minor).action(ArgAction::SetTrue)).arg(arg!(--patch auto inc patch).action(ArgAction::SetTrue))// Arguments can also be added to a group individually, these two arguments// are part of the input group which is not required.arg(arg!([INPUT_FILE] some regular input).value_parser(value_parser!(PathBuf))).arg(arg!(--spec-in SPEC_IN some special input argument).value_parser(value_parser!(PathBuf)),)// Now lets assume we have a -c [config] argument which requires one of// (but **not** both) the input arguments.arg(arg!(config: -c CONFIG).value_parser(value_parser!(PathBuf)));let matches cmd.get_matches_mut();// Lets assume the old version 1.2.3let mut major 1;let mut minor 2;let mut patch 3;// See if --set-ver was used to set the version manuallylet version if let Some(ver) matches.get_one::String(set-ver) {if matches.get_flag(major) || matches.get_flag(minor) || matches.get_flag(patch) {cmd.error(ErrorKind::ArgumentConflict,Cant do relative and absolute version change,).exit();}ver.to_string()} else {// Increment the one requested (in a real program, wed reset the lower numbers)let (maj, min, pat) (matches.get_flag(major),matches.get_flag(minor),matches.get_flag(patch),);match (maj, min, pat) {(true, false, false) major 1,(false, true, false) minor 1,(false, false, true) patch 1,_ {cmd.error(ErrorKind::ArgumentConflict,Can only modify one version field,).exit();}};format!({major}.{minor}.{patch})};println!(Version: {version});// Check for usage of -cif matches.contains_id(config) {let input matches.get_one::PathBuf(INPUT_FILE).or_else(|| matches.get_one::PathBuf(spec-in)).unwrap_or_else(|| {cmd.error(ErrorKind::MissingRequiredArgument,INPUT_FILE or --spec-in is required when using --config,).exit()}).display();println!(Doing work using input {} and config {},input,matches.get_one::PathBuf(config).unwrap().display());} }1.6、子命令(Subcommand) 我们可以使用 Command::subcommand 方法添加子命令。每一个子命令都自己的版本、作者、参数和它的子命令。 use clap::{arg, command, Command};fn main() {let matches command!() // requires cargo feature.propagate_version(true).subcommand_required(true).arg_required_else_help(true).subcommand(Command::new(add).about(Adds files to myapp).arg(arg!([NAME])),).get_matches();match matches.subcommand() {Some((add, sub_matches)) println!(myapp add was used, name is: {:?},sub_matches.get_one::String(NAME)),_ unreachable!(Exhausted list of subcommands and subcommand_required prevents None),} }我们使用 Command::arg_required_else_help 如果参数不存在优雅的退出。使用 Command::propagate_version 可以打印命令的版本号 1.7、测试 我们可以使用 debug_assert! 宏 或者 使用 Command::debug_assert 方法。 use clap::{arg, command, value_parser};fn main() {let matches cmd().get_matches();// Note, its safe to call unwrap() because the arg is requiredlet port: usize *matches.get_one::usize(PORT).expect(PORT is required and parsing will fail if its missing);println!(PORT {port}); }fn cmd() - clap::Command {command!() // requires cargo feature.arg(arg!(PORT).help(Network port to use).value_parser(value_parser!(usize)),) }#[test] fn verify_cmd() {cmd().debug_assert(); }二、 Clap 使用方式二derive feature 2.1、添加依赖 cargo add clap --features derive使用这种方式更加符合我们面向对象的设计方案。 2.2、快速开始 use std::path::PathBuf;use clap::{Parser, Subcommand};#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {/// Optional name to operate onname: OptionString,/// Sets a custom config file#[arg(short, long, value_name FILE)]config: OptionPathBuf,/// Turn debugging information on#[arg(short, long, action clap::ArgAction::Count)]debug: u8,#[command(subcommand)]command: OptionCommands, }#[derive(Subcommand)] enum Commands {/// does testing thingsTest {/// lists test values#[arg(short, long)]list: bool,}, }fn main() {let cli Cli::parse();// You can check the value provided by positional arguments, or option argumentsif let Some(name) cli.name.as_deref() {println!(Value for name: {name});}if let Some(config_path) cli.config.as_deref() {println!(Value for config: {}, config_path.display());}// You can see how many times a particular flag or argument occurred// Note, only flags can have multiple occurrencesmatch cli.debug {0 println!(Debug mode is off),1 println!(Debug mode is kind of on),2 println!(Debug mode is on),_ println!(Dont be crazy),}// You can check for the existence of subcommands, and if found use their// matches just as you would the top level cmdmatch cli.command {Some(Commands::Test { list }) {if *list {println!(Printing testing lists...);} else {println!(Not printing testing lists...);}}None {}}// Continued program logic goes here... }2.3、配置解析器 2.3.1、配置解析器 我们可以是 Parse 属性开启构建解析器 use clap::Parser;#[derive(Parser)] #[command(name MyApp)] #[command(author xiaojia)] #[command(version 1.0)] #[command(about 完成一些事情, long_about None)] struct Cli {#[arg(long)]two: String,#[arg(long)]one: String, }fn main() {let cli Cli::parse();println!(two: {:?}, cli.two);println!(one: {:?}, cli.one); }2.3.2、默认值 我们也可使用使用 #[command(author, version, about)] 形式从 Cargo.toml 读取配置消息 use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] // Read from Cargo.toml struct Cli {#[arg(long)]two: String,#[arg(long)]one: String, }fn main() {let cli Cli::parse();println!(two: {:?}, cli.two);println!(one: {:?}, cli.one); }2.3.3、Command::next_line_help 替代 我们可以使用 #[command(next_line_help true)] 方法替代 Command::next_line_help use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] #[command(next_line_help true)] struct Cli {#[arg(long)]two: String,#[arg(long)]one: String, }fn main() {let cli Cli::parse();println!(two: {:?}, cli.two);println!(one: {:?}, cli.one); }2.4、添加参数 2.4.1、添加可选参数 use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {name: OptionString, }fn main() {let cli Cli::parse();println!(name: {:?}, cli.name.as_deref()); }2.4.2、添加多值参数 use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {name: VecString, }fn main() {let cli Cli::parse();println!(name: {:?}, cli.name); }2.4.3、参数选项 2.4.3.1、短参数名称和长参数名称 我们可以使用 #[arg(short ‘n’)] 和 #[arg(long “name”)] 属性设置参数的短名称和长名称 use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {#[arg(short, long)]name: OptionString, }fn main() {let cli Cli::parse();println!(name: {:?}, cli.name.as_deref()); }2.4.3.2、开启和关闭 use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {#[arg(short, long)]verbose: bool, }fn main() {let cli Cli::parse();println!(verbose: {:?}, cli.verbose); }需要注意我们默认调用的是clap::ArgAction::SetTrue 2.4.3.3、参数计数 use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {#[arg(short, long, action clap::ArgAction::Count)]verbose: u8, }fn main() {let cli Cli::parse();println!(verbose: {:?}, cli.verbose); }2.4.3.4、参数默认值 我们使用 #[arg(default_value_t)] 属性来给参数设置默认值 use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {#[arg(default_value_t 2020)]port: u16, }fn main() {let cli Cli::parse();println!(port: {:?}, cli.port); }2.4.3.5、参数枚举 我们使用 #[arg(value_enum)] 设置参数枚举 结合枚举类 use clap::{Parser, ValueEnum};#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {/// What mode to run the program in#[arg(value_enum)]mode: Mode, }#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] enum Mode {/// Run swiftlyFast,/// Crawl slowly but steadily////// This paragraph is ignored because there is no long help text for possible values.Slow, }fn main() {let cli Cli::parse();match cli.mode {Mode::Fast {println!(Hare);}Mode::Slow {println!(Tortoise);}} }2.4.3.6、参数校验 use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {/// Network port to use#[arg(value_parser clap::value_parser!(u16).range(1..))]port: u16, }fn main() {let cli Cli::parse();println!(PORT {}, cli.port); }2.4.3.7、自定义解析 use std::ops::RangeInclusive;use clap::Parser;#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {/// Network port to use#[arg(value_parser port_in_range)]port: u16, }fn main() {let cli Cli::parse();println!(PORT {}, cli.port); }const PORT_RANGE: RangeInclusiveusize 1..65535;fn port_in_range(s: str) - Resultu16, String {let port: usize s.parse().map_err(|_| format!({s} isnt a port number))?;if PORT_RANGE.contains(port) {Ok(port as u16)} else {Err(format!(port not in range {}-{},PORT_RANGE.start(),PORT_RANGE.end()))} }2.4.3.8、参数关系 use clap::{Args, Parser};#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {#[command(flatten)]vers: Vers,/// some regular input#[arg(group input)]input_file: OptionString,/// some special input argument#[arg(long, group input)]spec_in: OptionString,#[arg(short, requires input)]config: OptionString, }#[derive(Args)] #[group(required true, multiple false)] struct Vers {/// set version manually#[arg(long, value_name VER)]set_ver: OptionString,/// auto inc major#[arg(long)]major: bool,/// auto inc minor#[arg(long)]minor: bool,/// auto inc patch#[arg(long)]patch: bool, }fn main() {let cli Cli::parse();// Lets assume the old version 1.2.3let mut major 1;let mut minor 2;let mut patch 3;// See if --set_ver was used to set the version manuallylet vers cli.vers;let version if let Some(ver) vers.set_ver.as_deref() {ver.to_string()} else {// Increment the one requested (in a real program, wed reset the lower numbers)let (maj, min, pat) (vers.major, vers.minor, vers.patch);match (maj, min, pat) {(true, _, _) major 1,(_, true, _) minor 1,(_, _, true) patch 1,_ unreachable!(),};format!({major}.{minor}.{patch})};println!(Version: {version});// Check for usage of -cif let Some(config) cli.config.as_deref() {let input cli.input_file.as_deref().unwrap_or_else(|| cli.spec_in.as_deref().unwrap());println!(Doing work using input {input} and config {config});} }2.4.3.9、自定义校验 use clap::error::ErrorKind; use clap::{CommandFactory, Parser};#[derive(Parser)] #[command(author, version, about, long_about None)] struct Cli {/// set version manually#[arg(long, value_name VER)]set_ver: OptionString,/// auto inc major#[arg(long)]major: bool,/// auto inc minor#[arg(long)]minor: bool,/// auto inc patch#[arg(long)]patch: bool,/// some regular inputinput_file: OptionString,/// some special input argument#[arg(long)]spec_in: OptionString,#[arg(short)]config: OptionString, }fn main() {let cli Cli::parse();// Lets assume the old version 1.2.3let mut major 1;let mut minor 2;let mut patch 3;// See if --set-ver was used to set the version manuallylet version if let Some(ver) cli.set_ver.as_deref() {if cli.major || cli.minor || cli.patch {let mut cmd Cli::command();cmd.error(ErrorKind::ArgumentConflict,Cant do relative and absolute version change,).exit();}ver.to_string()} else {// Increment the one requested (in a real program, wed reset the lower numbers)let (maj, min, pat) (cli.major, cli.minor, cli.patch);match (maj, min, pat) {(true, false, false) major 1,(false, true, false) minor 1,(false, false, true) patch 1,_ {let mut cmd Cli::command();cmd.error(ErrorKind::ArgumentConflict,Can only modify one version field,).exit();}};format!({major}.{minor}.{patch})};println!(Version: {version});// Check for usage of -cif let Some(config) cli.config.as_deref() {let input cli.input_file.as_deref()// or is preferred to or_else here since Option::as_deref is const.or(cli.spec_in.as_deref()).unwrap_or_else(|| {let mut cmd Cli::command();cmd.error(ErrorKind::MissingRequiredArgument,INPUT_FILE or --spec-in is required when using --config,).exit()});println!(Doing work using input {input} and config {config});} }2.5、子命令 我们使用 #[command(subcommand)] 属性和#[derive(Subcommand)] 联合起来使用声明子命令。 use clap::{Parser, Subcommand};#[derive(Parser)] #[command(author, version, about, long_about None)] #[command(propagate_version true)] struct Cli {#[command(subcommand)]command: Commands, }#[derive(Subcommand)] enum Commands {/// Adds files to myappAdd { name: OptionString }, }fn main() {let cli Cli::parse();// You can check for the existence of subcommands, and if found use their// matches just as you would the top level cmdmatch cli.command {Commands::Add { name } {println!(myapp add was used, name is: {name:?})}} }三、如何选择 我们需要注意 clap 的yaml 支持在新版本之中转移到了 clap_serde 库了。 我们建议使用 derive APi因为此种方式跟容易阅读、修改更加保持参数声明和参数读取同步更容易复用符合面向对象设计。 我们也可以使用 fncmd 库来实现命令行接口像函数一样使用。 总结
文章转载自:
http://www.morning.xnbd.cn.gov.cn.xnbd.cn
http://www.morning.wrfk.cn.gov.cn.wrfk.cn
http://www.morning.wklhn.cn.gov.cn.wklhn.cn
http://www.morning.wqngt.cn.gov.cn.wqngt.cn
http://www.morning.hwlk.cn.gov.cn.hwlk.cn
http://www.morning.rtbj.cn.gov.cn.rtbj.cn
http://www.morning.wptrm.cn.gov.cn.wptrm.cn
http://www.morning.jppb.cn.gov.cn.jppb.cn
http://www.morning.thntp.cn.gov.cn.thntp.cn
http://www.morning.bntgy.cn.gov.cn.bntgy.cn
http://www.morning.zbjfq.cn.gov.cn.zbjfq.cn
http://www.morning.kncrc.cn.gov.cn.kncrc.cn
http://www.morning.qmtzq.cn.gov.cn.qmtzq.cn
http://www.morning.yhplt.cn.gov.cn.yhplt.cn
http://www.morning.kqpxb.cn.gov.cn.kqpxb.cn
http://www.morning.wqgr.cn.gov.cn.wqgr.cn
http://www.morning.ykrkb.cn.gov.cn.ykrkb.cn
http://www.morning.yfphk.cn.gov.cn.yfphk.cn
http://www.morning.ldnrf.cn.gov.cn.ldnrf.cn
http://www.morning.jkszt.cn.gov.cn.jkszt.cn
http://www.morning.mwnch.cn.gov.cn.mwnch.cn
http://www.morning.kbqbx.cn.gov.cn.kbqbx.cn
http://www.morning.ctswj.cn.gov.cn.ctswj.cn
http://www.morning.youngbase.cn.gov.cn.youngbase.cn
http://www.morning.yydeq.cn.gov.cn.yydeq.cn
http://www.morning.tymwx.cn.gov.cn.tymwx.cn
http://www.morning.cptzd.cn.gov.cn.cptzd.cn
http://www.morning.dmhs.cn.gov.cn.dmhs.cn
http://www.morning.sphft.cn.gov.cn.sphft.cn
http://www.morning.kbdjn.cn.gov.cn.kbdjn.cn
http://www.morning.snnkt.cn.gov.cn.snnkt.cn
http://www.morning.zqbrw.cn.gov.cn.zqbrw.cn
http://www.morning.fcftj.cn.gov.cn.fcftj.cn
http://www.morning.sgfpn.cn.gov.cn.sgfpn.cn
http://www.morning.qgzmz.cn.gov.cn.qgzmz.cn
http://www.morning.plchy.cn.gov.cn.plchy.cn
http://www.morning.hcgbm.cn.gov.cn.hcgbm.cn
http://www.morning.skbbt.cn.gov.cn.skbbt.cn
http://www.morning.hrpjx.cn.gov.cn.hrpjx.cn
http://www.morning.qlry.cn.gov.cn.qlry.cn
http://www.morning.gklxm.cn.gov.cn.gklxm.cn
http://www.morning.xrhst.cn.gov.cn.xrhst.cn
http://www.morning.pudejun.com.gov.cn.pudejun.com
http://www.morning.ljbm.cn.gov.cn.ljbm.cn
http://www.morning.jgttx.cn.gov.cn.jgttx.cn
http://www.morning.dbfp.cn.gov.cn.dbfp.cn
http://www.morning.ntqlz.cn.gov.cn.ntqlz.cn
http://www.morning.zrhhb.cn.gov.cn.zrhhb.cn
http://www.morning.thbqp.cn.gov.cn.thbqp.cn
http://www.morning.pzcjq.cn.gov.cn.pzcjq.cn
http://www.morning.yxbrn.cn.gov.cn.yxbrn.cn
http://www.morning.wdnkp.cn.gov.cn.wdnkp.cn
http://www.morning.kflbf.cn.gov.cn.kflbf.cn
http://www.morning.tynqy.cn.gov.cn.tynqy.cn
http://www.morning.ykwgl.cn.gov.cn.ykwgl.cn
http://www.morning.xdmsq.cn.gov.cn.xdmsq.cn
http://www.morning.4r5w91.cn.gov.cn.4r5w91.cn
http://www.morning.wnrcj.cn.gov.cn.wnrcj.cn
http://www.morning.bfybb.cn.gov.cn.bfybb.cn
http://www.morning.pndw.cn.gov.cn.pndw.cn
http://www.morning.npgwb.cn.gov.cn.npgwb.cn
http://www.morning.dhqyh.cn.gov.cn.dhqyh.cn
http://www.morning.fmdvbsa.cn.gov.cn.fmdvbsa.cn
http://www.morning.hpkr.cn.gov.cn.hpkr.cn
http://www.morning.pwqyd.cn.gov.cn.pwqyd.cn
http://www.morning.fhqdb.cn.gov.cn.fhqdb.cn
http://www.morning.rbkgp.cn.gov.cn.rbkgp.cn
http://www.morning.rqbr.cn.gov.cn.rqbr.cn
http://www.morning.mzpd.cn.gov.cn.mzpd.cn
http://www.morning.qsmdd.cn.gov.cn.qsmdd.cn
http://www.morning.mnqz.cn.gov.cn.mnqz.cn
http://www.morning.xctdn.cn.gov.cn.xctdn.cn
http://www.morning.ltpph.cn.gov.cn.ltpph.cn
http://www.morning.lxcwh.cn.gov.cn.lxcwh.cn
http://www.morning.dspqc.cn.gov.cn.dspqc.cn
http://www.morning.yhljc.cn.gov.cn.yhljc.cn
http://www.morning.cbtn.cn.gov.cn.cbtn.cn
http://www.morning.mpbgy.cn.gov.cn.mpbgy.cn
http://www.morning.xdnhw.cn.gov.cn.xdnhw.cn
http://www.morning.xsfg.cn.gov.cn.xsfg.cn
http://www.tj-hxxt.cn/news/249428.html

相关文章:

  • 网站建设定价户县网站建设
  • 网站开发东莞如何创建一个网站
  • 杭州滨江区抖音seo行情windows优化大师有哪些功能
  • 合肥工程建设交易中心网站想用vs做网站 学什么
  • 简单的网站设计开发网站建设基本流程包括哪几个步骤
  • 新网站建设的感想四川网站建设找哪家
  • wordpress 网站运行时间咸阳做网站开发公司哪家好
  • 涉县企业做网站推广四川住房和建设厅网站
  • 网站的备案号百度知道个人中心
  • 如何用文档做网站用易语言做抢购网站软件
  • 帝国做的网站石岩网站建设 0755
  • 选择电商网站建设wordpress模板站如何安装
  • 做网站的开场白常州企业自助建站系统
  • 整站排名服务推广策略研究
  • 南昌知名的网站建设公司100大看免费行情的软件
  • 太仓网站制作书生wordpress在哪修改代码
  • 建水县住房和城乡建设局网站遵义会议在线
  • 工程建设指挥部网站网站建设落地页
  • 什邡建设局网站门户网站开发报价
  • 嵊州门户网站深圳制作网站建设推广
  • 基于目的地的o2o旅游电子商务网站开发设计毕业设计网站文章更新怎么做
  • 良精网站管理系统装修网站效果图
  • 深圳安鸿源建设网站网站开发公司 郑州
  • 关于建设网站安全性合同网站建好后如何上线
  • dedecms新网站 上传到万网的空间三亚哪里做网站
  • 做网站的你选题的缘由是什么全球设计师
  • 公司网站 仿站什么意思中文搭建式软件开发工具
  • 网站建设需要用到什么建设网站我们重中之重-用户体验
  • 四川省城乡住房与建设厅网站首页郑州企业的网站建设
  • 做家教什么网站制作网站单页