From 319d4cd56bbebe080b81b8b110285119523108dd Mon Sep 17 00:00:00 2001 From: ARCJ137442 <61109168+ARCJ137442@users.noreply.github.com> Date: Thu, 12 Sep 2024 21:11:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20:recycle:=20=E4=BB=8E=20BabelNAR.rs?= =?UTF-8?q?=20=E8=BF=81=E5=85=A5=E6=A8=A1=E5=9D=97=EF=BC=9A`cli=5Fsupport`?= =?UTF-8?q?=20=E2=87=92=20`crate::support`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 导入旧模块代码,并随之更新`use`代码和模块结构 --- Cargo.toml | 12 ++-- src/cli/arg_parse.rs | 8 ++- src/cli/config_launcher.rs | 12 ++-- src/cli/config_search.rs | 8 +-- src/cli/mod.rs | 100 +++++++++++++++++++++++++++++---- src/cli/runtime_manage.rs | 12 ++-- src/cli/vm_config.rs | 4 +- src/cli/websocket_server.rs | 4 +- src/lib.rs | 4 ++ src/main.rs | 70 +---------------------- src/support/io/mod.rs | 18 +++--- src/support/io/output_print.rs | 12 ++-- src/support/mod.rs | 10 ++-- src/tests/mod.rs | 88 +++++++++++++++++------------ 14 files changed, 196 insertions(+), 166 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8b4a721..c61a0a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,11 +58,13 @@ version = "0.17" # 现已发布于`crates.io` features = [] # ! 【2024-03-21 09:24:51】暂时没有特性 [dependencies.babel_nar] -version = "0.25" -features = [ # * 🚩【2024-09-12 18:04:39】目前锁定以下两个特性 - "cin_implements", # 各大CIN的NAVM实现 - "test_tools", # 测试工具集 -] +path = "../BabelNAR.rs" # TODO: 待BabelNAR.rs发布后恢复 +features = ["bundled"] +# version = "0.25" +# features = [ # * 🚩【2024-09-12 18:04:39】目前锁定以下两个特性 +# "cin_implements", # 各大CIN的NAVM实现 +# "test_tools", # 测试工具集 +# ] ## 依赖特性的可选依赖 ## diff --git a/src/cli/arg_parse.rs b/src/cli/arg_parse.rs index 95c1604..a29d6ee 100644 --- a/src/cli/arg_parse.rs +++ b/src/cli/arg_parse.rs @@ -2,8 +2,10 @@ //! * ⚠️【2024-04-01 14:31:09】特定于二进制crate,目前不要并入[`babel_nar`] //! * 🚩【2024-04-04 03:03:58】现在移出所有与「启动配置」相关的逻辑到[`super::vm_config`] -use crate::cli::{load_config_extern, read_config_extern, LaunchConfig}; -use babel_nar::println_cli; +use crate::{ + cli::{load_config_extern, read_config_extern, LaunchConfig}, + println_cli, +}; use clap::Parser; use std::{ env::{current_dir, current_exe}, @@ -113,7 +115,7 @@ pub fn load_config(args: &CliArgs) -> LaunchConfig { #[cfg(test)] mod tests { use super::*; - use babel_nar::tests::*; + use crate::tests::*; use nar_dev_utils::fail_tests; /// 测试/参数解析 diff --git a/src/cli/config_launcher.rs b/src/cli/config_launcher.rs index 4938530..4f25454 100644 --- a/src/cli/config_launcher.rs +++ b/src/cli/config_launcher.rs @@ -1,16 +1,18 @@ //! 用于从「启动参数」启动NAVM运行时 -use crate::cli::{ - read_config_extern, search_configs, LaunchConfig, LaunchConfigCommand, LaunchConfigTranslators, - RuntimeConfig, SUPPORTED_CONFIG_EXTENSIONS, +use crate::{ + cli::{ + read_config_extern, search_configs, LaunchConfig, LaunchConfigCommand, + LaunchConfigTranslators, RuntimeConfig, SUPPORTED_CONFIG_EXTENSIONS, + }, + eprintln_cli, println_cli, + support::{cin_search::name_match::name_match, io::readline_iter::ReadlineIter}, }; use anyhow::{anyhow, Result}; use babel_nar::{ cin_implements::{ common::generate_command, cxin_js, nars_python, native, ona, openjunars, opennars, pynars, }, - cli_support::{cin_search::name_match::name_match, io::readline_iter::ReadlineIter}, - eprintln_cli, println_cli, runtimes::{ api::{InputTranslator, IoTranslators}, CommandVm, OutputTranslator, diff --git a/src/cli/config_search.rs b/src/cli/config_search.rs index f953251..dce0fd9 100644 --- a/src/cli/config_search.rs +++ b/src/cli/config_search.rs @@ -1,11 +1,9 @@ //! CIN自动搜索 use crate::cli::{read_config_extern, LaunchConfig}; +use crate::println_cli; +use crate::support::cin_search::{name_match::is_name_match, path_walker::PathWalkerV1}; use anyhow::Result; -use babel_nar::{ - cli_support::cin_search::{name_match::is_name_match, path_walker::PathWalkerV1}, - println_cli, -}; use nar_dev_utils::ToDebug; use std::path::{Path, PathBuf}; @@ -81,7 +79,7 @@ pub fn search_configs>( #[cfg(test)] mod tests { use super::*; - use babel_nar::tests::config_paths::ARG_PARSE_TEST; + use crate::tests::config_paths::ARG_PARSE_TEST; // use std::env::current_dir; #[test] diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 5f2a9fe..4173bf6 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,17 +1,93 @@ //! 原BabelNAR.rs `src/bin/babelnar_cli/*.rs` //! * 🚩【2024-09-12 17:41:35】现在统一放置在`src/cli`下 -nar_dev_utils::mods! { - // 启动参数 - pub use vm_config; - // 命令行解析 - pub use arg_parse; - // 配置(自动)搜索 - pub use config_search; - // 从配置启动 - pub use config_launcher; +use crate::{eprintln_cli, println_cli}; +use anyhow::Result; +use clap::Parser; +use std::{io::Result as IoResult, path::PathBuf, thread::sleep, time::Duration}; + +// 启动参数 +mod vm_config; +pub use vm_config::*; + +// 命令行解析 +mod arg_parse; +pub use arg_parse::*; + +// 配置(自动)搜索 +mod config_search; +pub use config_search::*; + +// 从配置启动 +mod config_launcher; +pub use config_launcher::*; + +// 运行时交互、管理 +mod runtime_manage; +pub use runtime_manage::*; + +// Websocket服务端 +mod websocket_server; +pub use websocket_server::*; + +/// 以特定参数开始命令行主程序 +/// * 🚩此处只应该有自[`env`]传入的参数 +/// * 🚩【2024-04-01 14:25:38】暂时用不到「当前工作路径」 +pub fn main_args(cwd: IoResult, args: impl Iterator) -> Result<()> { + // 解包当前工作目录 + let cwd = cwd + .inspect_err(|e| println_cli!([Warn] "无法获取当前工作目录:{e}")) + .ok(); + + // (Windows下)启用终端颜色 + let _ = colored::control::set_virtual_terminal(true) + .inspect_err(|_| eprintln_cli!([Error] "无法启动终端彩色显示。。")); + + // 解析命令行参数 + let args = CliArgs::parse_from(args); + + // 读取配置 | with 默认配置文件 + let mut config = load_config(&args); + + // 是否向用户展示「详细信息」 | 用于等待、提示等 + let user_verbose = config.user_input.is_none() || config.user_input.unwrap(); + + // 用户填充配置项 | 需要用户输入、工作路径(🎯自动搜索) + polyfill_config_from_user(&mut config, cwd); + + // 清屏,预备启动 + if user_verbose { + println_cli!([Info] "配置加载完毕!程序将在1s后启动。。。"); + sleep(Duration::from_secs(1)); + } + let _ = clearscreen::clear().inspect_err(|e| eprintln_cli!([Warn] "清屏失败:{e}")); + + // 从配置项启动 | 复制一个新配置,不会附带任何非基础类型开销 + let (runtime, config) = match launch_by_config(config.clone()) { + // 启动成功⇒返回 + Ok((r, c)) => (r, c), + // 启动失败⇒打印错误信息,等待并退出 + Err(e) => { + println_cli!([Error] "NARS运行时启动错误:{e}"); + // 空配置/启用用户输入⇒延时提示 + if user_verbose { + println_cli!([Info] "程序将在 3 秒后自动退出。。。"); + sleep(Duration::from_secs(3)); + } + return Err(e); + } + }; + // 运行时交互、管理 - pub use runtime_manage; - // Websocket服务端 - pub use websocket_server; + let manager = RuntimeManager::new(runtime, config.clone()); + let result = loop_manage(manager, &config); + + // 启用用户输入时延时提示 + if config.user_input { + println_cli!([Info] "程序将在 5 秒后自动退出。。。"); + sleep(Duration::from_secs(3)); + } + + // 返回结果 + result } diff --git a/src/cli/runtime_manage.rs b/src/cli/runtime_manage.rs index e50db7d..d2de78d 100644 --- a/src/cli/runtime_manage.rs +++ b/src/cli/runtime_manage.rs @@ -1,17 +1,19 @@ //! 启动后运行时的(交互与)管理 use super::websocket_server::*; -use crate::cli::{launch_by_runtime_config, InputMode, LaunchConfigPreludeNAL, RuntimeConfig}; -use anyhow::{anyhow, Result}; -use babel_nar::{ - cli_support::{ +use crate::{ + cli::{launch_by_runtime_config, InputMode, LaunchConfigPreludeNAL, RuntimeConfig}, + eprintln_cli, if_let_err_eprintln_cli, println_cli, + support::{ error_handling_boost::error_anyhow, io::{ navm_output_cache::{ArcMutex, OutputCache}, readline_iter::ReadlineIter, }, }, - eprintln_cli, if_let_err_eprintln_cli, println_cli, +}; +use anyhow::{anyhow, Result}; +use babel_nar::{ runtimes::TranslateError, test_tools::{nal_format::parse, put_nal, VmOutputCache}, }; diff --git a/src/cli/vm_config.rs b/src/cli/vm_config.rs index 340f07e..abd4479 100644 --- a/src/cli/vm_config.rs +++ b/src/cli/vm_config.rs @@ -61,8 +61,8 @@ //! } //! ``` +use crate::println_cli; use anyhow::{anyhow, Result}; -use babel_nar::println_cli; use nar_dev_utils::{if_return, pipe, OptionBoost, ResultBoost}; use serde::{Deserialize, Serialize}; use std::{ @@ -742,8 +742,8 @@ pub fn try_complete_path(path: &Path) -> PathBuf { #[cfg(test)] pub mod tests { use super::*; + use crate::tests::*; use anyhow::Result; - use babel_nar::tests::*; use nar_dev_utils::{asserts, macro_once}; /// 测试/解析 diff --git a/src/cli/websocket_server.rs b/src/cli/websocket_server.rs index cc5da08..5826837 100644 --- a/src/cli/websocket_server.rs +++ b/src/cli/websocket_server.rs @@ -4,8 +4,8 @@ use crate::cli::{LaunchConfigWebsocket, RuntimeConfig, RuntimeManager}; use anyhow::Result; -use babel_nar::{ - cli_support::{ +use crate::{ + support::{ error_handling_boost::error_anyhow, io::{ navm_output_cache::{ArcMutex, OutputCache}, diff --git a/src/lib.rs b/src/lib.rs index b2927a4..9e5dfff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,3 +7,7 @@ pub mod support; // CLI主程序功能 pub mod cli; + +// 单元测试 +#[cfg(test)] +mod tests; diff --git a/src/main.rs b/src/main.rs index 5693d15..3e5dd7a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,79 +8,11 @@ //! ``` use anyhow::Result; -use babel_nar::{eprintln_cli, println_cli}; use babel_nar_cli::cli::*; -use clap::Parser; -use std::{env, io::Result as IoResult, path::PathBuf, thread::sleep, time::Duration}; +use std::env; /// 主入口 pub fn main() -> Result<()> { // 以默认参数启动 main_args(env::current_dir(), env::args()) } - -/// 以特定参数开始命令行主程序 -/// * 🚩此处只应该有自[`env`]传入的参数 -/// * 🚩【2024-04-01 14:25:38】暂时用不到「当前工作路径」 -pub fn main_args(cwd: IoResult, args: impl Iterator) -> Result<()> { - // 解包当前工作目录 - let cwd = cwd - .inspect_err(|e| println_cli!([Warn] "无法获取当前工作目录:{e}")) - .ok(); - - // (Windows下)启用终端颜色 - let _ = colored::control::set_virtual_terminal(true) - .inspect_err(|_| eprintln_cli!([Error] "无法启动终端彩色显示。。")); - - // 解析命令行参数 - let args = CliArgs::parse_from(args); - - // 读取配置 | with 默认配置文件 - let mut config = load_config(&args); - - // 是否向用户展示「详细信息」 | 用于等待、提示等 - let user_verbose = config.user_input.is_none() || config.user_input.unwrap(); - - // 用户填充配置项 | 需要用户输入、工作路径(🎯自动搜索) - polyfill_config_from_user(&mut config, cwd); - - // 清屏,预备启动 - if user_verbose { - println_cli!([Info] "配置加载完毕!程序将在1s后启动。。。"); - sleep(Duration::from_secs(1)); - } - let _ = clearscreen::clear().inspect_err(|e| eprintln_cli!([Warn] "清屏失败:{e}")); - - // 从配置项启动 | 复制一个新配置,不会附带任何非基础类型开销 - let (runtime, config) = match launch_by_config(config.clone()) { - // 启动成功⇒返回 - Ok((r, c)) => (r, c), - // 启动失败⇒打印错误信息,等待并退出 - Err(e) => { - println_cli!([Error] "NARS运行时启动错误:{e}"); - // 空配置/启用用户输入⇒延时提示 - if user_verbose { - println_cli!([Info] "程序将在 3 秒后自动退出。。。"); - sleep(Duration::from_secs(3)); - } - return Err(e); - } - }; - - // 运行时交互、管理 - let manager = RuntimeManager::new(runtime, config.clone()); - let result = loop_manage(manager, &config); - - // 启用用户输入时延时提示 - if config.user_input { - println_cli!([Info] "程序将在 5 秒后自动退出。。。"); - sleep(Duration::from_secs(3)); - } - - // 返回结果 - result -} - -// 单元测试 -#[cfg(test)] -mod tests; diff --git a/src/support/io/mod.rs b/src/support/io/mod.rs index f53bcd4..f238e95 100644 --- a/src/support/io/mod.rs +++ b/src/support/io/mod.rs @@ -2,16 +2,14 @@ //! * ✨终端美化相关 //! -nar_dev_utils::mods! { - // 输出打印 - pub output_print; +// 输出打印 +pub mod output_print; - // 读取行迭代器 - pub readline_iter; +// 读取行迭代器 +pub mod readline_iter; - // NAVM输出缓存 - pub navm_output_cache; +// NAVM输出缓存 +pub mod navm_output_cache; - // Websocket支持 - pub websocket; -} +// Websocket支持 +pub mod websocket; diff --git a/src/support/io/output_print.rs b/src/support/io/output_print.rs index 32bcbf0..d7f33be 100644 --- a/src/support/io/output_print.rs +++ b/src/support/io/output_print.rs @@ -242,17 +242,17 @@ macro_rules! println_cli { // 消息 | ✨可格式化 ([$enum_type_name:ident] $($tail:tt)*) => { // 调用内部函数 - $crate::cli_support::io::output_print::OutputType::$enum_type_name.print_line(&format!($($tail)*)); + $crate::support::io::output_print::OutputType::$enum_type_name.print_line(&format!($($tail)*)) }; // NAVM输出 表达式 ($navm_output:expr) => { // 调用内部函数 - $crate::cli_support::io::output_print::OutputType::print_navm_output($navm_output); + $crate::support::io::output_print::OutputType::print_navm_output($navm_output) }; // NAVM输出 表达式 | 🪄详细 (% $navm_output:expr) => { // 调用内部函数 - $crate::cli_support::io::output_print::OutputType::print_navm_output_verbose($navm_output); + $crate::support::io::output_print::OutputType::print_navm_output_verbose($navm_output) }; } @@ -262,17 +262,17 @@ macro_rules! eprintln_cli { // 消息 | ✨可格式化 ([$enum_type_name:ident] $($tail:tt)*) => { // 调用内部函数 - $crate::cli_support::io::output_print::OutputType::$enum_type_name.eprint_line(&format!($($tail)*)); + $crate::support::io::output_print::OutputType::$enum_type_name.eprint_line(&format!($($tail)*)) }; // NAVM输出 表达式 ($navm_output:expr) => { // 调用内部函数 - $crate::cli_support::io::output_print::OutputType::eprint_navm_output($navm_output); + $crate::support::io::output_print::OutputType::eprint_navm_output($navm_output) }; // NAVM输出 表达式 | 🪄详细 (% $navm_output:expr) => { // 调用内部函数 - $crate::cli_support::io::output_print::OutputType::eprint_navm_output_verbose($navm_output); + $crate::support::io::output_print::OutputType::eprint_navm_output_verbose($navm_output) }; } diff --git a/src/support/mod.rs b/src/support/mod.rs index 66cb24a..e60fc4a 100644 --- a/src/support/mod.rs +++ b/src/support/mod.rs @@ -5,13 +5,11 @@ //! * 🎯通用、可选地复用「CIN启动器」等「命令行工具」的内容 //! * 🎯亦可为后续基于UI的应用提供支持 -nar_dev_utils::mods! { - // CIN搜索 - pub cin_search; +// CIN搜索 +pub mod cin_search; - // 输入输出 - pub io; -} +// 输入输出 +pub mod io; // 错误处理增强 pub mod error_handling_boost; diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 94d9e2d..cdc7750 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,8 +1,10 @@ //! 单元测试 #![allow(unused_attributes)] -use super::*; +use crate::cli::main_args; +use anyhow::Result; use nar_dev_utils::list; +use std::env; /// 测试用配置文件路径 /// * 🎯后续其它地方统一使用该处路径 @@ -14,12 +16,26 @@ use nar_dev_utils::list; pub mod config_paths; use config_paths::*; +/// 测试用宏/找不到路径即退出 +/// * 🚩输入一个`&str`,构建`&Path`并在其不存在时退出程序,或返回该`&Path`对象 +#[macro_export] +macro_rules! exists_or_exit { + ($path:expr) => {{ + let path = std::path::Path::new($path); + if !path.exists() { + println!("所需路径 {path:?} 不存在,已自动退出"); + std::process::exit(0) + } + path + }}; +} + /// 通用测试入口 /// * 🎯通用、可复用的启动代码 /// * 🎯跨不同CIN通用 /// * 🎯跨同CIN不同测试通用 pub fn main(cin_config_path: &str, other_args: &[&str]) -> Result<()> { - babel_nar::exists_or_exit!("./executables"); + exists_or_exit!("./executables"); // 以默认参数启动 main_args( env::current_dir(), @@ -54,44 +70,44 @@ pub fn main_configs(cin_config_path: &str, other_config_paths: &[&str]) -> Resul /// 批量生成「预引入NAL」 macro_rules! cin_tests { - ( - $(#[$attr_root:meta])* - $cin_path:ident; // ! ❌若为`expr`,则会和上边的修饰符导致「本地歧义」 - $( - $(#[$attr:meta])* - $name:ident => $config_path:expr $(;)? - )* - ) => { - /// 主Shell - /// * 🎯正常BabelNAR CLI shell启动 - /// * 🎯正常用户命令行交互体验 - $(#[$attr_root])* - #[test] - #[ignore = "仅作试运行用,不用于自动化测试"] - pub fn main_shell() -> Result<()> { - main($cin_path, &[]) - } +( + $(#[$attr_root:meta])* + $cin_path:ident; // ! ❌若为`expr`,则会和上边的修饰符导致「本地歧义」 + $( + $(#[$attr:meta])* + $name:ident => $config_path:expr $(;)? + )* +) => { + /// 主Shell + /// * 🎯正常BabelNAR CLI shell启动 + /// * 🎯正常用户命令行交互体验 + $(#[$attr_root])* + #[test] + #[ignore = "仅作试运行用,不用于自动化测试"] + pub fn main_shell() -> Result<()> { + main($cin_path, &[]) + } + + /// Matriangle服务器 + /// * 🎯复现先前基于Matriangle环境的NARS实验 + $(#[$attr_root])* + #[test] + #[ignore = "仅作试运行用,不用于自动化测试"] + pub fn main_matriangle_server() -> Result<()> { + // 以默认参数启动 + main_configs($cin_path, &[MATRIANGLE_SERVER]) + } - /// Matriangle服务器 - /// * 🎯复现先前基于Matriangle环境的NARS实验 - $(#[$attr_root])* + $( + $(#[$attr])* #[test] - #[ignore = "仅作试运行用,不用于自动化测试"] - pub fn main_matriangle_server() -> Result<()> { - // 以默认参数启动 - main_configs($cin_path, &[MATRIANGLE_SERVER]) + #[ignore = "【2024-06-12 23:52:35】不用于自动化测试:会自动清屏影响测试结果呈现"] + pub fn $name() -> Result<()> { + main_configs($cin_path, &[PRELUDE_TEST, $config_path]) } - - $( - $(#[$attr])* - #[test] - #[ignore = "【2024-06-12 23:52:35】不用于自动化测试:会自动清屏影响测试结果呈现"] - pub fn $name() -> Result<()> { - main_configs($cin_path, &[PRELUDE_TEST, $config_path]) - } - )* - }; + )* +}; } /// 测试/ONA