diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-02-26 15:37:05 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-02-26 15:37:05 +0800 |
| commit | 9420a530e371747cd6df79a5f3bbbf814effe949 (patch) | |
| tree | 029039bc4cba61e421d62ccecfae565ab3ed9b5d /src/systems | |
| parent | 981d244df444d3dcf48dee558109231da7e6a61b (diff) | |
Add verbose logging support with env_logger
Diffstat (limited to 'src/systems')
| -rw-r--r-- | src/systems/cmd/cmd_system.rs | 83 | ||||
| -rw-r--r-- | src/systems/cmd/processer.rs | 31 | ||||
| -rw-r--r-- | src/systems/debug.rs | 1 | ||||
| -rw-r--r-- | src/systems/debug/verbose_logger.rs | 43 |
4 files changed, 125 insertions, 33 deletions
diff --git a/src/systems/cmd/cmd_system.rs b/src/systems/cmd/cmd_system.rs index 1fe6e66..57aa15d 100644 --- a/src/systems/cmd/cmd_system.rs +++ b/src/systems/cmd/cmd_system.rs @@ -1,3 +1,6 @@ +use log::{error, info}; +use rust_i18n::t; + use crate::{ r_println, systems::{ @@ -6,11 +9,13 @@ use crate::{ }, }; use std::{ - any::{Any, TypeId}, + any::{Any, TypeId, type_name}, collections::HashMap, future::Future, }; +rust_i18n::i18n!("resources/locales/jvn", fallback = "en"); + pub struct JVCommandContext { pub help: bool, pub confirmed: bool, @@ -42,39 +47,17 @@ where return Err(CmdProcessError::RendererOverrideButRequestHelp); } + info!("{}", t!("verbose.cmd_process")); let (data, type_id) = Self::process(args, ctx).await?; - let renderer_override = renderer_override.as_str(); + let renderer = renderer_override.as_str(); // Serialize the data based on its concrete type - let render_result: Result<JVRenderResult, CmdRenderError> = if type_id - == std::any::TypeId::of::<crate::cmds::out::hex::JVHexOutput>() - { - let concrete_data = data - .downcast::<crate::cmds::out::hex::JVHexOutput>() - .map_err(|_| CmdProcessError::DowncastFailed)?; - include!("../render/_override_renderer_dispatcher.rs") - } else if type_id - == std::any::TypeId::of::<crate::cmds::out::mappings::JVMappingsOutput>() - { - let concrete_data = data - .downcast::<crate::cmds::out::mappings::JVMappingsOutput>() - .map_err(|_| CmdProcessError::DowncastFailed)?; - include!("../render/_override_renderer_dispatcher.rs") - } else if type_id == std::any::TypeId::of::<crate::cmds::out::status::JVStatusOutput>() - { - let concrete_data = data - .downcast::<crate::cmds::out::status::JVStatusOutput>() - .map_err(|_| CmdProcessError::DowncastFailed)?; - include!("../render/_override_renderer_dispatcher.rs") - } else { - return Err(CmdProcessError::NoMatchingCommand); - }; - - match render_result { - Ok(r) => Ok(r), - Err(e) => Err(CmdProcessError::Render(e)), - } + info!( + "{}", + t!("verbose.render_with_override_renderer", renderer = renderer) + ); + include!("../render/_override_renderer_entry.rs") } } @@ -93,7 +76,10 @@ where return Ok(r); } + info!("{}", t!("verbose.cmd_process")); let (data, id) = Self::process(args, ctx).await?; + + info!("{}", t!("verbose.render_with_specific_renderer")); match render(data, id).await { Ok(r) => Ok(r), Err(e) => Err(CmdProcessError::Render(e)), @@ -111,22 +97,53 @@ where full_args.extend(args); + info!( + "{}", + t!("verbose.cmd_process_parse", t = type_name::<Argument>()) + ); + let parsed_args = match Argument::try_parse_from(full_args) { Ok(args) => args, - Err(_) => return Err(CmdProcessError::ParseError(Self::get_help_str())), + Err(_) => { + error!( + "{}", + t!( + "verbose.cmd_process_parse_failed", + t = type_name::<Argument>() + ) + ); + return Err(CmdProcessError::ParseError(Self::get_help_str())); + } }; + info!( + "{}", + t!( + "verbose.cmd_process_prepare", + i = type_name::<Input>(), + c = type_name::<Collect>() + ) + ); + let (input, collect) = match tokio::try_join!( Self::prepare(&parsed_args, &ctx), Self::collect(&parsed_args, &ctx) ) { Ok((input, collect)) => (input, collect), - Err(e) => return Err(CmdProcessError::from(e)), + Err(e) => { + error!("{}", t!("verbose.cmd_process_prepare_failed")); + return Err(CmdProcessError::from(e)); + } }; + info!("{}", t!("verbose.cmd_process_exec")); + let data = match Self::exec(input, collect).await { Ok(output) => output, - Err(e) => return Err(CmdProcessError::from(e)), + Err(e) => { + error!("{}", t!("verbose.cmd_process_exec_failed")); + return Err(CmdProcessError::from(e)); + } }; Ok(data) diff --git a/src/systems/cmd/processer.rs b/src/systems/cmd/processer.rs index 196764a..0f68afb 100644 --- a/src/systems/cmd/processer.rs +++ b/src/systems/cmd/processer.rs @@ -1,13 +1,20 @@ +use log::{error, info, warn}; +use rust_i18n::t; + use crate::systems::cmd::_commands::{jv_cmd_nodes, jv_cmd_process_node}; use crate::systems::cmd::cmd_system::JVCommandContext; use crate::systems::cmd::errors::CmdProcessError; use crate::systems::render::renderer::JVRenderResult; +rust_i18n::i18n!("resources/locales/jvn", fallback = "en"); + pub async fn jv_cmd_process( args: &Vec<String>, ctx: JVCommandContext, renderer_override: String, ) -> Result<JVRenderResult, CmdProcessError> { + info!("{}", t!("verbose.cmd_process_start")); + let nodes = jv_cmd_nodes(); // Why add a space? @@ -27,10 +34,18 @@ pub async fn jv_cmd_process( match matching_nodes.len() { 0 => { // No matching node found + error!("{}", t!("verbose.cmd_match_no_node")); return Err(CmdProcessError::NoMatchingCommand); } 1 => { let matched_prefix = matching_nodes[0]; + + // DEBUG + info!( + "{}", + t!("verbose.cmd_match_matched_single", node = matched_prefix) + ); + let prefix_len = matched_prefix.split_whitespace().count(); let trimmed_args: Vec<String> = args.into_iter().cloned().skip(prefix_len).collect(); return jv_cmd_process_node(matched_prefix, trimmed_args, ctx, renderer_override).await; @@ -39,6 +54,22 @@ pub async fn jv_cmd_process( // Multiple matching nodes found // Find the node with the longest length (most specific match) let matched_prefix = matching_nodes.iter().max_by_key(|node| node.len()).unwrap(); + + // DEBUG + let nodes_str = matching_nodes + .iter() + .map(|s| s.as_str()) + .collect::<Vec<_>>() + .join(", "); + warn!( + "{}", + t!( + "verbose.cmd_match_matched_multi", + nodes = nodes_str, + node = matched_prefix + ) + ); + let prefix_len = matched_prefix.split_whitespace().count(); let trimmed_args: Vec<String> = args.into_iter().cloned().skip(prefix_len).collect(); return jv_cmd_process_node(matched_prefix, trimmed_args, ctx, renderer_override).await; diff --git a/src/systems/debug.rs b/src/systems/debug.rs new file mode 100644 index 0000000..be544e8 --- /dev/null +++ b/src/systems/debug.rs @@ -0,0 +1 @@ +pub mod verbose_logger; diff --git a/src/systems/debug/verbose_logger.rs b/src/systems/debug/verbose_logger.rs new file mode 100644 index 0000000..ceb8bd8 --- /dev/null +++ b/src/systems/debug/verbose_logger.rs @@ -0,0 +1,43 @@ +use chrono::Local; +use env_logger::Builder; +use log::Level; +use rust_i18n::t; +use std::io::Write; + +rust_i18n::i18n!("resources/locales/jvn", fallback = "en"); + +pub fn init_verbose_logger(level_filter: Option<log::LevelFilter>) { + let mut builder = match level_filter { + Some(f) => { + let mut b = Builder::new(); + b.filter_level(f); + b + } + None => return, + }; + + builder + .format(|buf, record| { + let now = Local::now(); + let timestamp = now.format("%y-%-m-%-d %H:%M:%S"); + let level = record.level(); + let args = record.args(); + + let (prefix, color_code) = match level { + Level::Error => (t!("logger.error").trim().to_string(), "\x1b[31m"), + Level::Warn => (t!("logger.warn").trim().to_string(), "\x1b[33m"), + Level::Info => (t!("logger.info").trim().to_string(), "\x1b[37m"), + Level::Debug => (t!("logger.debug").trim().to_string(), "\x1b[90m"), + Level::Trace => (t!("logger.trace").trim().to_string(), "\x1b[36m"), + }; + + let colored_prefix = if prefix.is_empty() { + String::new() + } else { + format!("{}[{}] {}: \x1b[0m", color_code, timestamp, prefix) + }; + + writeln!(buf, "{}{}", colored_prefix, args) + }) + .init(); +} |
