summaryrefslogtreecommitdiff
path: root/src/systems
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-02-26 15:37:05 +0800
committer魏曹先生 <1992414357@qq.com>2026-02-26 15:37:05 +0800
commit9420a530e371747cd6df79a5f3bbbf814effe949 (patch)
tree029039bc4cba61e421d62ccecfae565ab3ed9b5d /src/systems
parent981d244df444d3dcf48dee558109231da7e6a61b (diff)
Add verbose logging support with env_logger
Diffstat (limited to 'src/systems')
-rw-r--r--src/systems/cmd/cmd_system.rs83
-rw-r--r--src/systems/cmd/processer.rs31
-rw-r--r--src/systems/debug.rs1
-rw-r--r--src/systems/debug/verbose_logger.rs43
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();
+}