Rust命令行工具开发库proto_cli的使用,快速构建高效CLI应用与协议处理工具
Rust命令行工具开发库proto_cli的使用,快速构建高效CLI应用与协议处理工具
proto是一个可插拔的新一代多编程语言版本管理器。它是一个统一的工具链。
为什么使用proto?
- 极速!使用Rust,我们可以保证卓越的性能
- 多语言支持。一个CLI即可管理所有语言的版本
- 跨平台,提供一致的机器和团队体验
- 上下文版本检测,确保始终使用正确的工具版本
- 校验和验证,确保工具来自可信来源
- 检测并推断语言生态系统以实现最大兼容性
- 通过WASM的可插拔架构,支持自定义集成
支持的语言
- Bun
- Deno
- Go
- moon
- Node (以及 npm, pnpm, yarn)
- Python (以及 poetry, uv)
- Ruby
- Rust
- 以及更多通过插件支持的语言
示例代码
这里是一个使用proto_cli构建基本CLI工具的示例:
use proto_cli::{Proto, ProtoCommand, ProtoError};
fn main() -> Result<(), ProtoError> {
// 创建Proto实例
let mut proto = Proto::new();
// 添加命令
proto.add_command(
ProtoCommand::new("version")
.about("显示proto版本信息")
.action(|_| {
println!("proto version: {}", env!("CARGO_PKG_VERSION"));
Ok(())
})
);
// 添加另一个命令示例
proto.add_command(
ProtoCommand::new("install")
.about("安装工具版本")
.arg("<tool>", "要安装的工具名称")
.arg("[version]", "要安装的版本")
.action(|args| {
let tool = args.get_str("<tool>")?;
let version = args.get_opt_str("[version]");
println!("正在安装 {} 版本 {:?}", tool, version);
// 这里添加实际的安装逻辑
Ok(())
})
);
// 运行CLI
proto.run()
}
完整示例Demo
下面是一个更完整的CLI应用示例,展示了proto_cli的主要功能:
use proto_cli::{Proto, ProtoCommand, ProtoError, ProtoArgs};
use std::path::PathBuf;
fn main() -> Result<(), ProtoError> {
let mut proto = Proto::new()
.name("mycli")
.version("1.0.0")
.about("一个示例CLI工具");
// 添加版本命令
proto.add_command(
ProtoCommand::new("version")
.about("显示版本信息")
.action(|_| {
println!("mycli version 1.0.0");
Ok(())
})
);
// 添加安装命令
proto.add_command(
ProtoCommand::new("install")
.about("安装工具")
.arg("<tool>", "要安装的工具名称")
.arg("[version]", "要安装的特定版本")
.flag("--global", "全局安装")
.action(|args| {
let tool = args.get_str("<tool>")?;
let version = args.get_opt_str("[version]");
let global = args.contains_flag("--global");
println!("安装配置:");
println!("- 工具: {}", tool);
println!("- 版本: {:?}", version);
println!("- 全局: {}", global);
// 这里添加实际的安装逻辑
Ok(())
})
);
// 添加配置命令
proto.add_command(
ProtoCommand::new("config")
.about("管理配置")
.subcommand(
ProtoCommand::new("set")
.about("设置配置值")
.arg("<key>", "配置键")
.arg("<value>", "配置值")
.action(|args| {
let key = args.get_str("<key>")?;
let value = args.get_str("<value>")?;
println!("设置配置 {} = {}", key, value);
Ok(())
})
)
.subcommand(
ProtoCommand::new("get")
.about("获取配置值")
.arg("<key>", "配置键")
.action(|args| {
let key = args.get_str("<key>")?;
println!("获取配置 {} = (模拟值)", key);
Ok(())
})
)
);
// 添加复杂命令示例
proto.add_command(
ProtoCommand::new("complex")
.about("复杂命令示例")
.arg("<input>", "输入文件路径")
.option("--output <path>", "输出文件路径")
.flag("--verbose", "显示详细输出")
.action(|args| {
let input = PathBuf::from(args.get_str("<input>")?);
let output = args.get_opt_str("--output")
.map(PathBuf::from);
let verbose = args.contains_flag("--verbose");
println!("处理文件:");
println!("- 输入: {:?}", input);
if let Some(out) = output {
println!("- 输出: {:?}", out);
}
println!("- 详细模式: {}", verbose);
// 添加实际的文件处理逻辑
Ok(())
})
);
// 运行CLI
proto.run()
}
贡献者
特别感谢为这个项目做出贡献的优秀人员:
安装
cargo install proto_cli
运行上述命令将全局安装proto
和proto-shim
二进制文件。
1 回复
Rust命令行工具开发库proto_cli的使用指南
概述
proto_cli
是一个用于快速构建高效命令行界面(CLI)应用的Rust库,特别适合需要处理协议数据的工具开发。它提供了简洁的API和强大的功能,帮助开发者快速实现命令行工具。
主要特性
- 简洁的命令行参数解析
- 内置协议处理功能
- 自动生成帮助信息
- 支持子命令
- 高效错误处理
安装
在Cargo.toml
中添加依赖:
[dependencies]
proto_cli = "0.3.0"
基本使用方法
1. 创建简单CLI应用
use proto_cli::{ProtoApp, ProtoCommand, ProtoArg};
fn main() {
// 创建新的CLI应用
let app = ProtoApp::new("myapp")
.version("1.0.0")
.author("Your Name")
.about("A simple CLI application")
.arg(ProtoArg::new("input")
.short('i')
.long("input")
.help("Input file path")
.required(true))
.arg(ProtoArg::new("output")
.short('o')
.long("output")
.help("Output file path"));
// 解析命令行参数
let matches = app.get_matches();
// 获取参数值
let input = matches.value_of("input").unwrap();
let output = matches.value_of("output").unwrap_or("default.txt");
println!("Processing {} to {}", input, output);
}
2. 使用子命令
use proto_cli::{ProtoApp, ProtoCommand};
fn main() {
// 创建带子命令的CLI应用
let app = ProtoApp::new("network-tool")
.subcommand(ProtoCommand::new("send")
.about("Send data to a server")
.arg(ProtoArg::new("host")
.required(true)
.help("Server host address")))
.subcommand(ProtoCommand::new("receive")
.about("Receive data from a server")
.arg(ProtoArg::new("port")
.short('p')
.help("Port to listen on")));
// 解析命令行参数
let matches = app.get_matches();
// 处理子命令
match matches.subcommand() {
Some(("send", sub_m)) => {
let host = sub_m.value_of("host").unwrap();
println!("Sending data to {}", host);
}
Some(("receive", sub_m)) => {
let port = sub_m.value_of("port").unwrap_or("8080");
println!("Listening on port {}", port);
}
_ => unreachable!(),
}
}
3. 协议处理功能
use proto_cli::{ProtoApp, ProtoCommand};
use proto_cli::protocol::{Protocol, ProtocolType};
fn main() {
// 创建协议分析工具
let app = ProtoApp::new("protocol-analyzer")
.arg(ProtoArg::new("protocol")
.short('p')
.long("protocol")
.help("Protocol type (http, tcp, udp)")
.required(true))
.arg(ProtoArg::new("data")
.help("Data to analyze")
.required(true));
// 解析命令行参数
let matches = app.get_matches();
// 获取参数值
let protocol_type = matches.value_of("protocol").unwrap();
let data = matches.value_of("data").unwrap();
// 创建协议处理器并分析数据
let protocol = Protocol::new(ProtocolType::from_str(protocol_type).unwrap());
let analysis = protocol.analyze(data);
println!("Analysis result: {:?}", analysis);
}
高级功能
自定义验证器
use proto_cli::{ProtoApp, ProtoArg};
// 自定义端口验证函数
fn validate_port(port: &str) -> Result<(), String> {
port.parse::<u16>()
.map(|_| ())
.map_err(|_| format!("'{}' is not a valid port number", port))
}
fn main() {
// 创建带验证器的CLI应用
let app = ProtoApp::new("port-checker")
.arg(ProtoArg::new("port")
.validator(validate_port)
.required(true));
let matches = app.get_matches();
let port = matches.value_of("port").unwrap();
println!("Valid port: {}", port);
}
自动补全支持
use proto_cli::{ProtoApp, ProtoCommand, ProtoArg};
fn main() {
// 创建支持自动补全的CLI应用
let app = ProtoApp::new("autocomplete-demo")
.arg(ProtoArg::new("mode")
.possible_values(&["fast", "slow", "debug"])
.required(true));
// 生成补全脚本
// 通常在build.rs中调用
// ProtoApp::gen_completions("myapp", Shell::Bash, "./completions");
}
完整示例Demo
下面是一个结合多个特性的完整示例,展示如何构建一个功能完善的网络工具:
use proto_cli::{ProtoApp, ProtoCommand, ProtoArg};
use proto_cli::protocol::{Protocol, ProtocolType};
use std::sync::Arc;
// 自定义验证器 - 验证IP地址格式
fn validate_ip(ip: &str) -> Result<(), String> {
if ip.split('.').count() == 4 &&
ip.split('.').all(|s| s.parse::<u8>().is_ok()) {
Ok(())
} else {
Err(format!("'{}' is not a valid IPv4 address", ip))
}
}
fn main() {
// 共享数据
let shared_config = Arc::new("v1.0-config".to_string());
// 创建CLI应用
let app = ProtoApp::new("network-utils")
.version("1.0.0")
.author("Network Team")
.about("Advanced network utilities")
// 全局参数
.arg(ProtoArg::new("verbose")
.short('v')
.long("verbose")
.help("Enable verbose output"))
// 子命令 - ping
.subcommand(ProtoCommand::new("ping")
.about("Ping a network host")
.arg(ProtoArg::new("host")
.validator(validate_ip)
.required(true)
.help("Host to ping")))
// 子命令 - analyze
.subcommand(ProtoCommand::new("analyze")
.about("Analyze protocol data")
.arg(ProtoArg::new("protocol")
.short('p')
.long("protocol")
.possible_values(&["http", "tcp", "udp"])
.required(true)
.help("Protocol type"))
.arg(ProtoArg::new("data")
.required(true)
.help("Data to analyze")));
// 解析参数
let matches = app.get_matches();
// 处理全局verbose标志
let verbose = matches.is_present("verbose");
if verbose {
println!("Running in verbose mode with config: {}", shared_config);
}
// 处理子命令
match matches.subcommand() {
Some(("ping", sub_m)) => {
let host = sub_m.value_of("host").unwrap();
println!("Pinging {}...", host);
// 实际ping逻辑...
}
Some(("analyze", sub_m)) => {
let protocol_type = sub_m.value_of("protocol").unwrap();
let data = sub_m.value_of("data").unwrap();
let protocol = Protocol::new(ProtocolType::from_str(protocol_type).unwrap());
let analysis = protocol.analyze(data);
println!("Analysis result:");
println!("Protocol: {}", protocol_type);
println!("Data size: {} bytes", data.len());
println!("Details: {:?}", analysis);
}
_ => {
println!("No subcommand specified. Use --help for usage information.");
}
}
}
最佳实践
- 对于复杂的CLI应用,使用子命令组织功能
- 为所有参数和子命令添加详细的帮助信息
- 使用验证器确保输入数据的有效性
- 考虑为常用工具添加自动补全支持
- 使用
Protocol
特性处理特定协议数据时,遵循相关RFC标准
性能提示
- 避免在参数解析过程中进行大量计算
- 对于频繁调用的工具,考虑使用
Arc
共享数据 - 使用
Protocol
的批处理模式处理大量数据
proto_cli
通过简洁的API和强大的功能,使得开发命令行工具变得更加高效和愉快。无论是简单的脚本还是复杂的协议分析工具,都能从中受益。