splited
This commit is contained in:
+28
-51
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::cmds::{Command, args_optional, raw_args};
|
||||
use crate::cfg::*;
|
||||
use crate::help::{build_help, help_entity_type};
|
||||
use crate::help::{build_help, build_app_help_msg, help_entity_type, app_help_handler, print_command_help};
|
||||
|
||||
pub struct App {
|
||||
name: String,
|
||||
@@ -18,57 +18,21 @@ impl App {
|
||||
}
|
||||
|
||||
pub fn build_help_msg(&self) -> String {
|
||||
let author = &self.author;
|
||||
let license = &self.license;
|
||||
let aim = &self.aim;
|
||||
let name = &self.name;
|
||||
|
||||
let mut help_msg = String::new();
|
||||
help_msg.push_str(&format!("{}\n", family_statement));
|
||||
help_msg.push_str(&format!("This App is developed by {} and distributed under {}.\n", author, license));
|
||||
help_msg.push_str(&format!("aim: {}\n", aim));
|
||||
help_msg.push_str(&format!("usage: {} <operation> [...]\n", name));
|
||||
help_msg.push_str("operations:\n");
|
||||
|
||||
for cmd in &self.commands {
|
||||
let cmd_short_name = cmd.short_name();
|
||||
let cmd_long_name = cmd.long_name();
|
||||
let args_info = match &cmd.args_optional {
|
||||
args_optional::Optional => " [args] [optional_arguments]",
|
||||
args_optional::Required => " <args> <required_arguments>",
|
||||
args_optional::NoArgs => "",
|
||||
};
|
||||
help_msg.push_str(&format!(" {} {{{} {}}}{} {}\n",
|
||||
name, cmd_short_name, cmd_long_name, args_info, cmd.description));
|
||||
}
|
||||
|
||||
help_msg.push_str("\nuse 'Command {-h --help}' with an operation for available options.\n");
|
||||
help_msg
|
||||
build_app_help_msg(&self.name, &self.author, &self.license, &self.aim, &self.commands)
|
||||
}
|
||||
|
||||
fn app_help_handler(&self, targets: Vec<String>) {
|
||||
//考虑无参数也就是应该输出app自身的帮助信息
|
||||
if targets.len() == 0 {
|
||||
let help_msg = self.build_help_msg();
|
||||
println_compat(&help_msg);
|
||||
}
|
||||
for cmd in targets {
|
||||
//这里应该根据cmd的名称拿到帮助信息
|
||||
for cmd_entity in &self.commands {
|
||||
if cmd_entity.matches(&cmd) { // [AI修改-需学习] 使用matches方法统一匹配
|
||||
let help_msg = cmd_entity.build_help_msg();
|
||||
println_compat(&help_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
app_help_handler(&help_msg, &self.commands, targets);
|
||||
}
|
||||
|
||||
|
||||
/// 注意逻辑严谨项:依赖不存在的指令,这是有些离谱的,这种去怪神人程序员,没那本事老老实实去用ide的改名功能
|
||||
/// 没事别写互相依赖这种,换个方式实现
|
||||
/// 我写的逻辑可能有问题,涉及到cmd名字的地方建议用全名
|
||||
pub fn run(self) {
|
||||
//根据依赖command的顺序运行各个command handler
|
||||
/// 构建命令执行顺序
|
||||
/// 返回: (执行队列, 未找到的命令列表)
|
||||
fn build_execution_order(&self) -> (Vec<String>, Vec<String>, HashMap<String, Vec<String>>) {
|
||||
//从环境变量中获取参数
|
||||
let mut args = std::env::args().collect::<Vec<String>>();
|
||||
// 跳过第一个参数(程序名)
|
||||
@@ -116,7 +80,7 @@ impl App {
|
||||
if !proced_queue.contains(cmd_name) { //这些是根部之外的
|
||||
//搜索这个名为cmd_name的依赖项并确认是否满足
|
||||
for cmd_entity in &self.commands {
|
||||
if cmd_entity.matches(cmd_name) { // [AI修改-需学习] 使用matches方法
|
||||
if cmd_entity.matches(cmd_name) {
|
||||
// 确认依赖项是否满足
|
||||
if cmd_entity.critical_dep_command_list.iter().all(|dep_cmd_ref| {
|
||||
proced_queue.iter().any(|proc_name| dep_cmd_ref.matches(proc_name))
|
||||
@@ -131,14 +95,26 @@ impl App {
|
||||
last_round_queue = proced_queue.clone();
|
||||
loop_count += 1;
|
||||
}
|
||||
|
||||
// 提取命令参数映射
|
||||
let mut cmd_args_map: HashMap<String, Vec<String>> = HashMap::new();
|
||||
for (cmd_name, (cmd_args, _)) in &whole_queue {
|
||||
cmd_args_map.insert(cmd_name.clone(), cmd_args.clone());
|
||||
}
|
||||
|
||||
(proced_queue, notfound_queue, cmd_args_map)
|
||||
}
|
||||
|
||||
/// 执行命令队列
|
||||
fn execute_commands(&self, proced_queue: &[String], cmd_args_map: &HashMap<String, Vec<String>>, notfound_queue: &[String]) {
|
||||
//无参数则执行help
|
||||
if proced_queue.is_empty() {
|
||||
self.app_help_handler(vec![]);
|
||||
}
|
||||
|
||||
// 执行所有已处理的命令
|
||||
for cmd_name in &proced_queue {
|
||||
if let Some((cmd_args, _)) = whole_queue.get(cmd_name) {
|
||||
for cmd_name in proced_queue {
|
||||
if let Some(cmd_args) = cmd_args_map.get(cmd_name) {
|
||||
// 查找对应的命令实体并执行handler
|
||||
for cmd_entity in &self.commands {
|
||||
if cmd_entity.matches(cmd_name) {
|
||||
@@ -155,6 +131,12 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(self) {
|
||||
//根据依赖command的顺序运行各个command handler
|
||||
let (proced_queue, notfound_queue, cmd_args_map) = self.build_execution_order();
|
||||
self.execute_commands(&proced_queue, &cmd_args_map, ¬found_queue);
|
||||
}
|
||||
|
||||
pub fn construct(author: String, license: String, aim: String, name: String) -> App {
|
||||
App{
|
||||
name: name,
|
||||
@@ -178,12 +160,7 @@ impl App {
|
||||
println_compat(&help_msg);
|
||||
}
|
||||
for cmd in needed_help_args {
|
||||
for cmd_entity in &app.commands {
|
||||
if cmd_entity.matches(&cmd) {
|
||||
let help_msg = cmd_entity.build_help_msg();
|
||||
println_compat(&help_msg);
|
||||
}
|
||||
}
|
||||
print_command_help(&app.commands, &cmd);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+45
-1
@@ -1,4 +1,4 @@
|
||||
use crate::cfg::{cmd_flag, display_in_a_line_args};
|
||||
use crate::cfg::{cmd_flag, display_in_a_line_args, family_statement, println_compat};
|
||||
use crate::cmds::{args_optional, Command, CommandRef};
|
||||
|
||||
impl Command {
|
||||
@@ -63,3 +63,47 @@ pub fn build_help(who_type: help_entity_type, help_info_prov: Box<dyn Fn(Vec<Str
|
||||
handler: help_info_prov
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_app_help_msg(name: &str, author: &str, license: &str, aim: &str, commands: &[Command]) -> String {
|
||||
let mut help_msg = String::new();
|
||||
help_msg.push_str(&format!("{}\n", family_statement));
|
||||
help_msg.push_str(&format!("This App is developed by {} and distributed under {}.\n", author, license));
|
||||
help_msg.push_str(&format!("aim: {}\n", aim));
|
||||
help_msg.push_str(&format!("usage: {} <operation> [...]\n", name));
|
||||
help_msg.push_str("operations:\n");
|
||||
|
||||
for cmd in commands {
|
||||
let cmd_short_name = cmd.short_name();
|
||||
let cmd_long_name = cmd.long_name();
|
||||
let args_info = match &cmd.args_optional {
|
||||
args_optional::Optional => " [args] [optional_arguments]",
|
||||
args_optional::Required => " <args> <required_arguments>",
|
||||
args_optional::NoArgs => "",
|
||||
};
|
||||
help_msg.push_str(&format!(" {} {{{} {}}}{} {}\n",
|
||||
name, cmd_short_name, cmd_long_name, args_info, cmd.description));
|
||||
}
|
||||
|
||||
help_msg.push_str("\nuse 'Command {-h --help}' with an operation for available options.\n");
|
||||
help_msg
|
||||
}
|
||||
|
||||
pub fn print_command_help(commands: &[Command], cmd_name: &str) {
|
||||
for cmd_entity in commands {
|
||||
if cmd_entity.matches(cmd_name) {
|
||||
let help_msg = cmd_entity.build_help_msg();
|
||||
println_compat(&help_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn app_help_handler(app_help_msg: &str, commands: &[Command], targets: Vec<String>) {
|
||||
//考虑无参数也就是应该输出app自身的帮助信息
|
||||
if targets.len() == 0 {
|
||||
println_compat(app_help_msg);
|
||||
}
|
||||
for cmd in targets {
|
||||
//这里应该根据cmd的名称拿到帮助信息
|
||||
print_command_help(commands, &cmd);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
pub mod app;
|
||||
pub mod cmds;
|
||||
mod cfg;
|
||||
mod help;
|
||||
pub mod app;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//Copyright (c) [2026] [S.A. @SNOWARE SALflake@aliyun.com]
|
||||
// [swpk::CmdEngine] is licensed under Mulan PubL v2.
|
||||
// You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
// You may obtain a copy of Mulan PubL v2 at:
|
||||
// http://license.coscl.org.cn/MulanPubL-2.0
|
||||
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
// See the Mulan PubL v2 for more details
|
||||
|
||||
// This file has been split into separate modules:
|
||||
// - cfg.rs: Configuration constants
|
||||
// - cmds.rs: Command and CommandRef definitions
|
||||
// - help.rs: Help system implementation
|
||||
// - app.rs: App structure and logic
|
||||
Reference in New Issue
Block a user