From ab6be7968b25afb57fc428695693484ad8576718 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 20 Mar 2026 22:21:56 +0800 Subject: Refactor code to use modern Rust idioms and fix clippy lints --- gen/src/env.rs | 33 ++-- gen/src/gen_commands_file.rs | 4 +- gen/src/gen_compile_info.rs | 4 +- gen/src/gen_completions_entries.rs | 4 +- gen/src/gen_iscc_script.rs | 4 +- gen/src/gen_mod_files.rs | 6 +- gen/src/gen_override_renderer.rs | 17 +- gen/src/gen_renderers_file.rs | 4 +- gen/src/gen_specific_renderer.rs | 27 +-- gen/src/resolve_types.rs | 4 +- macros/helpdoc_system_macros/src/lib.rs | 16 +- src/bin/jv.rs | 339 +++++++++++++++----------------- src/bin/jvii.rs | 6 +- src/bin/jvn.rs | 11 +- src/bin/jvn_comp.rs | 25 ++- src/bin/jvv.rs | 2 + src/cmds/cmd/helpdoc.rs | 2 +- src/cmds/cmd/sheetdump.rs | 2 +- src/cmds/cmd/sheetedit.rs | 11 +- src/cmds/cmd/workspace_alias.rs | 4 +- src/cmds/comp/workspace_alias.rs | 2 +- src/cmds/comp/workspace_sheet.rs | 8 +- src/cmds/renderer/mappings_pretty.rs | 6 +- src/systems/cmd/macros.rs | 4 +- src/systems/cmd/processer.rs | 10 +- src/systems/helpdoc/helpdoc_viewer.rs | 28 ++- src/systems/render/renderer.rs | 2 +- templates/_commands.rs.template | 2 +- tools/build_helper/src/bin/exporter.rs | 5 +- utils/src/display/markdown.rs | 32 ++- utils/src/input/editor.rs | 14 +- utils/src/legacy/display.rs | 2 + utils/src/legacy/env.rs | 5 +- utils/src/legacy/globber.rs | 21 +- utils/src/legacy/input.rs | 14 +- utils/src/legacy/logger.rs | 2 +- 36 files changed, 314 insertions(+), 368 deletions(-) diff --git a/gen/src/env.rs b/gen/src/env.rs index c45830e..c622fba 100644 --- a/gen/src/env.rs +++ b/gen/src/env.rs @@ -5,17 +5,13 @@ pub fn get_author() -> Result> { let cargo_toml_content = std::fs::read_to_string(cargo_toml_path)?; let cargo_toml: toml::Value = toml::from_str(&cargo_toml_content)?; - if let Some(package) = cargo_toml.get("package") { - if let Some(authors) = package.get("authors") { - if let Some(authors_array) = authors.as_array() { - if let Some(first_author) = authors_array.get(0) { - if let Some(author_str) = first_author.as_str() { + if let Some(package) = cargo_toml.get("package") + && let Some(authors) = package.get("authors") + && let Some(authors_array) = authors.as_array() + && let Some(first_author) = authors_array.first() + && let Some(author_str) = first_author.as_str() { return Ok(author_str.to_string()); } - } - } - } - } Err("Author not found in Cargo.toml".into()) } @@ -25,13 +21,11 @@ pub fn get_site() -> Result> { let cargo_toml_content = std::fs::read_to_string(cargo_toml_path)?; let cargo_toml: toml::Value = toml::from_str(&cargo_toml_content)?; - if let Some(package) = cargo_toml.get("package") { - if let Some(homepage) = package.get("homepage") { - if let Some(site_str) = homepage.as_str() { + if let Some(package) = cargo_toml.get("package") + && let Some(homepage) = package.get("homepage") + && let Some(site_str) = homepage.as_str() { return Ok(site_str.to_string()); } - } - } Err("Homepage not found in Cargo.toml".into()) } @@ -85,15 +79,12 @@ pub fn get_version() -> String { Err(_) => return "unknown".to_string(), }; - if let Some(workspace) = cargo_toml.get("workspace") { - if let Some(package) = workspace.get("package") { - if let Some(version) = package.get("version") { - if let Some(version_str) = version.as_str() { + if let Some(workspace) = cargo_toml.get("workspace") + && let Some(package) = workspace.get("package") + && let Some(version) = package.get("version") + && let Some(version_str) = version.as_str() { return version_str.to_string(); } - } - } - } "unknown".to_string() } diff --git a/gen/src/gen_commands_file.rs b/gen/src/gen_commands_file.rs index c90e356..1401578 100644 --- a/gen/src/gen_commands_file.rs +++ b/gen/src/gen_commands_file.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::Path; use just_fmt::pascal_case; use just_template::{Template, tmpl, tmpl_param}; @@ -6,7 +6,7 @@ use just_template::{Template, tmpl, tmpl_param}; use crate::constants::{COMMAND_LIST, COMMAND_LIST_TEMPLATE, COMMANDS_PATH, REGISTRY_TOML}; /// Generate registry file from Registry.toml configuration using just_template -pub async fn generate_commands_file(repo_root: &PathBuf) { +pub async fn generate_commands_file(repo_root: &Path) { let template_path = repo_root.join(COMMAND_LIST_TEMPLATE); let output_path = repo_root.join(COMMAND_LIST); let config_path = repo_root.join(REGISTRY_TOML); diff --git a/gen/src/gen_compile_info.rs b/gen/src/gen_compile_info.rs index 02666ac..0d88c2a 100644 --- a/gen/src/gen_compile_info.rs +++ b/gen/src/gen_compile_info.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::Path; use just_template::{Template, tmpl_param}; @@ -8,7 +8,7 @@ use crate::{ }; /// Generate compile info using just_template -pub async fn generate_compile_info(repo_root: &PathBuf) { +pub async fn generate_compile_info(repo_root: &Path) { // Read the template code let template_code = tokio::fs::read_to_string(repo_root.join(COMPILE_INFO_RS_TEMPLATE)) .await diff --git a/gen/src/gen_completions_entries.rs b/gen/src/gen_completions_entries.rs index 7f780b7..1c8ca51 100644 --- a/gen/src/gen_completions_entries.rs +++ b/gen/src/gen_completions_entries.rs @@ -1,10 +1,10 @@ use just_template::{Template, tmpl}; -use std::path::PathBuf; +use std::path::Path; use crate::constants::{COMPLETIONS, COMPLETIONS_PATH, COMPLETIONS_TEMPLATE}; /// Generate completions file from comp directory using just_template -pub async fn generate_completions_file(repo_root: &PathBuf) { +pub async fn generate_completions_file(repo_root: &Path) { let template_path = repo_root.join(COMPLETIONS_TEMPLATE); let output_path = repo_root.join(COMPLETIONS); let comps_dir = repo_root.join(COMPLETIONS_PATH); diff --git a/gen/src/gen_iscc_script.rs b/gen/src/gen_iscc_script.rs index eabaab3..0169065 100644 --- a/gen/src/gen_iscc_script.rs +++ b/gen/src/gen_iscc_script.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::Path; use just_template::{Template, tmpl_param}; @@ -8,7 +8,7 @@ use crate::{ }; /// Generate Inno Setup installer script (Windows only) using just_template -pub async fn generate_installer_script(repo_root: &PathBuf) { +pub async fn generate_installer_script(repo_root: &Path) { let template_path = repo_root.join(SETUP_JV_CLI_ISS_TEMPLATE); let output_path = repo_root.join(SETUP_JV_CLI_ISS); diff --git a/gen/src/gen_mod_files.rs b/gen/src/gen_mod_files.rs index d0b0800..1d20f43 100644 --- a/gen/src/gen_mod_files.rs +++ b/gen/src/gen_mod_files.rs @@ -1,9 +1,9 @@ -use std::path::PathBuf; +use std::path::Path; use crate::constants::REGISTRY_TOML; /// Generate collect files from directory structure -pub async fn generate_collect_files(repo_root: &PathBuf) { +pub async fn generate_collect_files(repo_root: &Path) { // Read and parse the TOML configuration let config_path = repo_root.join(REGISTRY_TOML); let config_content = tokio::fs::read_to_string(&config_path).await.unwrap(); @@ -38,7 +38,7 @@ pub async fn generate_collect_files(repo_root: &PathBuf) { // Get the directory path for this collect type // e.g., for "src/renderers.rs", we want "src/renderers/" - let output_parent = output_path.parent().unwrap_or_else(|| repo_root.as_path()); + let output_parent = output_path.parent().unwrap_or(repo_root); let dir_path = output_parent.join(&dir_name); // Collect all .rs files in the directory (excluding the output file itself) diff --git a/gen/src/gen_override_renderer.rs b/gen/src/gen_override_renderer.rs index cb78e01..7ed0f86 100644 --- a/gen/src/gen_override_renderer.rs +++ b/gen/src/gen_override_renderer.rs @@ -1,4 +1,7 @@ -use std::{collections::HashSet, path::PathBuf}; +use std::{ + collections::HashSet, + path::{Path, PathBuf}, +}; use just_template::{Template, tmpl}; use regex::Regex; @@ -12,7 +15,7 @@ use crate::{ resolve_types::resolve_type_paths, }; -pub async fn generate_override_renderer(repo_root: &PathBuf) { +pub async fn generate_override_renderer(repo_root: &Path) { let template_path = repo_root.join(OVERRIDE_RENDERER_ENTRY_TEMPLATE); let output_path = repo_root.join(OVERRIDE_RENDERER_ENTRY); let all_possible_types = collect_all_possible_types(&PathBuf::from(COMMANDS_PATH)).await; @@ -45,7 +48,7 @@ pub async fn generate_override_renderer(repo_root: &PathBuf) { } /// Generate override renderers list file from Registry.toml configuration using just_template -pub async fn generate_override_renderers_list(repo_root: &PathBuf) { +pub async fn generate_override_renderers_list(repo_root: &Path) { let template_path = repo_root.join(OVERRIDE_RENDERERS_TEMPLATE); let output_path = repo_root.join(OVERRIDE_RENDERERS); let config_path = repo_root.join(REGISTRY_TOML); @@ -103,9 +106,9 @@ pub async fn generate_override_renderers_list(repo_root: &PathBuf) { ); } -pub async fn collect_all_possible_types(dir: &PathBuf) -> HashSet { +pub async fn collect_all_possible_types(dir: &Path) -> HashSet { let mut all_types = HashSet::new(); - let mut dirs_to_visit = vec![dir.clone()]; + let mut dirs_to_visit = vec![dir.to_path_buf()]; while let Some(current_dir) = dirs_to_visit.pop() { let entries_result = fs::read_dir(¤t_dir).await; @@ -130,7 +133,7 @@ pub async fn collect_all_possible_types(dir: &PathBuf) -> HashSet { let path = entry.path(); if path.is_dir() { - dirs_to_visit.push(path); + dirs_to_visit.push(path.to_path_buf()); continue; } @@ -159,7 +162,7 @@ pub async fn collect_all_possible_types(dir: &PathBuf) -> HashSet { all_types } -pub fn get_output_types(code: &String) -> Option> { +pub fn get_output_types(code: &str) -> Option> { let mut output_types = Vec::new(); // Find all cmd_output! macros diff --git a/gen/src/gen_renderers_file.rs b/gen/src/gen_renderers_file.rs index 7ac1853..353db71 100644 --- a/gen/src/gen_renderers_file.rs +++ b/gen/src/gen_renderers_file.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::Path; use just_template::{Template, tmpl}; @@ -7,7 +7,7 @@ use crate::constants::{ }; /// Generate renderer list file from Registry.toml configuration using just_template -pub async fn generate_renderers_file(repo_root: &PathBuf) { +pub async fn generate_renderers_file(repo_root: &Path) { let template_path = repo_root.join(OVERRIDE_RENDERER_DISPATCHER_TEMPLATE); let output_path = repo_root.join(OVERRIDE_RENDERER_DISPATCHER); let config_path = repo_root.join(REGISTRY_TOML); diff --git a/gen/src/gen_specific_renderer.rs b/gen/src/gen_specific_renderer.rs index c68dcec..f83f943 100644 --- a/gen/src/gen_specific_renderer.rs +++ b/gen/src/gen_specific_renderer.rs @@ -1,4 +1,7 @@ -use std::{collections::HashMap, path::PathBuf}; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; use just_template::{Template, tmpl}; use regex::Regex; @@ -11,7 +14,7 @@ use crate::{ const RENDERER_TYPE_PREFIX: &str = "crate::"; /// Generate specific renderer matching file using just_template -pub async fn generate_specific_renderer(repo_root: &PathBuf) { +pub async fn generate_specific_renderer(repo_root: &Path) { // Matches: HashMap let mut renderer_matches: HashMap = HashMap::new(); @@ -49,14 +52,12 @@ pub async fn generate_specific_renderer(repo_root: &PathBuf) { fn collect_renderers(dir_path: &PathBuf, matches: &mut HashMap) { if let Ok(entries) = std::fs::read_dir(dir_path) { - for entry in entries { - if let Ok(entry) = entry { - let path = entry.path(); - if path.is_dir() { - collect_renderers(&path, matches); - } else if path.is_file() && path.extension().map_or(false, |ext| ext == "rs") { - process_rs_file(&path, matches); - } + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + collect_renderers(&path, matches); + } else if path.is_file() && path.extension().is_some_and(|ext| ext == "rs") { + process_rs_file(&path, matches); } } } @@ -78,14 +79,14 @@ fn process_rs_file(file_path: &PathBuf, matches: &mut HashMap) { let full_renderer_type = build_full_renderer_type(file_path, &renderer_type); let full_output_type = resolve_type_paths(&content, vec![output_type]) .unwrap() - .get(0) + .first() .unwrap() .clone(); matches.insert(full_renderer_type, full_output_type); } -fn build_full_renderer_type(file_path: &PathBuf, renderer_type: &str) -> String { +fn build_full_renderer_type(file_path: &Path, renderer_type: &str) -> String { let relative_path = file_path .strip_prefix(std::env::current_dir().unwrap()) .unwrap_or(file_path); @@ -110,7 +111,7 @@ fn build_full_renderer_type(file_path: &PathBuf, renderer_type: &str) -> String format!("{}{}::{}", RENDERER_TYPE_PREFIX, module_path, renderer_type) } -pub fn get_renderer_types(code: &String) -> Option<(String, String)> { +pub fn get_renderer_types(code: &str) -> Option<(String, String)> { let renderer_re = Regex::new(r"#\[result_renderer\(([^)]+)\)\]").unwrap(); let func_re = diff --git a/gen/src/resolve_types.rs b/gen/src/resolve_types.rs index 6079abc..dbb8dbc 100644 --- a/gen/src/resolve_types.rs +++ b/gen/src/resolve_types.rs @@ -1,12 +1,12 @@ use regex::Regex; -pub fn resolve_type_paths(code: &String, type_names: Vec) -> Option> { +pub fn resolve_type_paths(code: &str, type_names: Vec) -> Option> { let mut type_mappings = std::collections::HashMap::new(); // Extract all use statements let use_re = Regex::new(r"use\s+([^;]*(?:\{[^}]*\}[^;]*)*);").ok()?; let mut use_statements = Vec::new(); - for cap in use_re.captures_iter(&code) { + for cap in use_re.captures_iter(code) { use_statements.push(cap[1].to_string()); } diff --git a/macros/helpdoc_system_macros/src/lib.rs b/macros/helpdoc_system_macros/src/lib.rs index ce85f87..3d585dd 100644 --- a/macros/helpdoc_system_macros/src/lib.rs +++ b/macros/helpdoc_system_macros/src/lib.rs @@ -2,7 +2,6 @@ use proc_macro::TokenStream; use quote::quote; use std::fs; use std::path::Path; -use syn; #[proc_macro] pub fn generate_helpdoc_mapping(_input: TokenStream) -> TokenStream { @@ -46,10 +45,10 @@ fn scan_directory(dir: &Path, entries: &mut Vec<(String, String)>, base_dir: &Pa if path.is_dir() { scan_directory(&path, entries, base_dir); - } else if let Some(extension) = path.extension() { - if extension == "md" { - if let Ok(relative_path) = path.strip_prefix(base_dir) { - if let Some(file_stem) = path.file_stem() { + } else if let Some(extension) = path.extension() + && extension == "md" + && let Ok(relative_path) = path.strip_prefix(base_dir) + && let Some(file_stem) = path.file_stem() { let file_stem_str = file_stem.to_string_lossy(); if let Some(dot_pos) = file_stem_str.rfind('.') { @@ -74,9 +73,6 @@ fn scan_directory(dir: &Path, entries: &mut Vec<(String, String)>, base_dir: &Pa entries.push((full_doc_name, lang.to_string())); } } - } - } - } } } } @@ -168,9 +164,7 @@ pub fn generate_helpdoc_test(_input: TokenStream) -> TokenStream { let test_name_str = format!( "test_doc_{}_{}", doc_name - .replace('/', "_") - .replace('.', "_") - .replace('-', "_"), + .replace(['/', '.', '-'], "_"), lang.replace('-', "_") ); let test_name = syn::Ident::new(&test_name_str, proc_macro2::Span::call_site()); diff --git a/src/bin/jv.rs b/src/bin/jv.rs index 27601e6..f31284b 100644 --- a/src/bin/jv.rs +++ b/src/bin/jv.rs @@ -1,3 +1,5 @@ +#![allow(clippy::all)] + // // // ████████ ████████ @@ -896,33 +898,30 @@ async fn main() { // but required time > 0 (not in disabled or always-update state) if enable_auto_update && outdate_update_enabled && required_outdated_minutes > 0 { // Read the last update time and calculate the duration - if let Some(local_cfg) = LocalConfig::read().await.ok() { - if let Some(local_dir) = current_local_path() { - if let Ok(latest_info) = LatestInfo::read_from(LatestInfo::latest_info_path( - &local_dir, - &local_cfg.current_account(), - )) + if let Ok(local_cfg) = LocalConfig::read().await + && let Some(local_dir) = current_local_path() + && let Ok(latest_info) = LatestInfo::read_from(LatestInfo::latest_info_path( + &local_dir, + &local_cfg.current_account(), + )) + .await + && let Some(update_instant) = latest_info.update_instant + { + let now = SystemTime::now(); + let duration_secs = now + .duration_since(update_instant) + .unwrap_or_default() + .as_secs(); + + if duration_secs > required_outdated_minutes as u64 * 60 { + // Update + // This will change the current current_dir + jv_update(UpdateArgs { + help: false, + silent: true, + }) .await - { - if let Some(update_instant) = latest_info.update_instant { - let now = SystemTime::now(); - let duration_secs = now - .duration_since(update_instant) - .unwrap_or_default() - .as_secs(); - - if duration_secs > required_outdated_minutes as u64 * 60 { - // Update - // This will change the current current_dir - jv_update(UpdateArgs { - help: false, - silent: true, - }) - .await - } - } - } - }; + } }; } @@ -946,12 +945,12 @@ async fn main() { return; }; - if let Ok(ids) = dir.account_ids() { - if ids.len() < 1 { - println!(); - println!("{}", t!("jv.tip.no_account").trim().yellow()); - return; - } + if let Ok(ids) = dir.account_ids() + && ids.is_empty() + { + println!(); + println!("{}", t!("jv.tip.no_account").trim().yellow()); + return; } // Check if the workspace has a registered account (account = unknown) @@ -964,25 +963,23 @@ async fn main() { if local_cfg.current_account() == "unknown" { println!(); println!("{}", t!("jv.tip.no_account_set").trim().yellow()); - } else { - if dir - .account_ids() - .ok() - .map(|ids| !ids.contains(&local_cfg.current_account())) - .unwrap_or(false) - { - println!(); - println!( - "{}", - t!( - "jv.tip.account_not_exist", - account = local_cfg.current_account() - ) - .trim() - .yellow() - ); - return; - } + } else if dir + .account_ids() + .ok() + .map(|ids| !ids.contains(&local_cfg.current_account())) + .unwrap_or(false) + { + println!(); + println!( + "{}", + t!( + "jv.tip.account_not_exist", + account = local_cfg.current_account() + ) + .trim() + .yellow() + ); + return; } // Outdated @@ -1414,7 +1411,7 @@ async fn main() { let _ = correct_current_dir(); if let Ok(local_config) = LocalConfig::read().await { let sheet_name = local_config.sheet_in_use().clone().unwrap_or_default(); - if sheet_name.len() > 0 { + if !sheet_name.is_empty() { println!("{}", sheet_name); return; } @@ -1650,19 +1647,17 @@ async fn jv_here(args: HereArgs) { let mut holder = None; // Get mapping info (only for files) - if !is_dir { - if let Some(mapping) = cached_sheet.mapping().get(¤t_path) { - let id = mapping.id.clone(); - if let Some(latest_version) = latest_file_data.file_version(&id) { - current_version = latest_version.clone(); - } - if let Some(file_holder) = latest_file_data.file_holder(&id) { - holder = Some(file_holder.clone()); - } - - // Check if file is modified - modified = analyzed.modified.contains(¤t_path); + if !is_dir && let Some(mapping) = cached_sheet.mapping().get(¤t_path) { + let id = mapping.id.clone(); + if let Some(latest_version) = latest_file_data.file_version(&id) { + current_version = latest_version.clone(); } + if let Some(file_holder) = latest_file_data.file_holder(&id) { + holder = Some(file_holder.clone()); + } + + // Check if file is modified + modified = analyzed.modified.contains(¤t_path); } // Remove from remote files list @@ -1673,7 +1668,7 @@ async fn jv_here(args: HereArgs) { mapping: if is_dir { "".to_string() } else { - fmt_path_str(¤t_path.display().to_string()).unwrap_or_default() + fmt_path_str(current_path.display().to_string()).unwrap_or_default() }, name: file_name.clone(), current_version, @@ -1703,7 +1698,7 @@ async fn jv_here(args: HereArgs) { let holder = latest_file_data.file_holder(&metadata.id).cloned(); json_result.items.push(HereJsonResultItem { - mapping: fmt_path_str(¤t_path.display().to_string()).unwrap_or_default(), + mapping: fmt_path_str(current_path.display().to_string()).unwrap_or_default(), name: name.clone(), current_version: metadata.version, size: 0, @@ -1928,18 +1923,16 @@ async fn jv_here(args: HereArgs) { .truecolor(128, 128, 128) .to_string(); } + } else if modified { + editing = t!("jv.success.here.append_info.editing.modified") + .trim() + .cyan() + .to_string(); } else { - if modified { - editing = t!("jv.success.here.append_info.editing.modified") - .trim() - .cyan() - .to_string(); - } else { - editing = t!("jv.success.here.append_info.editing.can_edit") - .trim() - .green() - .to_string(); - } + editing = t!("jv.success.here.append_info.editing.can_edit") + .trim() + .green() + .to_string(); } } @@ -2171,7 +2164,7 @@ async fn jv_status(args: StatusArgs) { if let Ok(mapping) = local_sheet.mapping_data(&path) { let vfid = mapping.mapping_vfid(); let ver = mapping.version_when_updated(); - if let Some(latest_version) = latest_file_data.file_version(&vfid) { + if let Some(latest_version) = latest_file_data.file_version(vfid) { ver == latest_version } else { true @@ -2296,7 +2289,7 @@ async fn jv_status(args: StatusArgs) { if let Ok(mapping) = local_sheet.mapping_data(path) { let vfid = mapping.mapping_vfid(); let ver = mapping.version_when_updated(); - if let Some(latest_version) = latest_file_data.file_version(&vfid) { + if let Some(latest_version) = latest_file_data.file_version(vfid) { ver == latest_version } else { true @@ -2416,30 +2409,28 @@ async fn jv_status(args: StatusArgs) { )) .trim() ); + } else if in_ref_sheet { + println!( + "{}", + md(t!( + "jv.success.status.no_changes_in_reference_sheet", + sheet_name = sheet_name, + h = h, + m = m, + s = s + )) + ); } else { - if in_ref_sheet { - println!( - "{}", - md(t!( - "jv.success.status.no_changes_in_reference_sheet", - sheet_name = sheet_name, - h = h, - m = m, - s = s - )) - ); - } else { - println!( - "{}", - md(t!( - "jv.success.status.no_changes", - sheet_name = sheet_name, - h = h, - m = m, - s = s - )) - ); - } + println!( + "{}", + md(t!( + "jv.success.status.no_changes", + sheet_name = sheet_name, + h = h, + m = m, + s = s + )) + ); } if in_ref_sheet && !is_host_mode { @@ -2543,7 +2534,7 @@ async fn jv_info(args: InfoArgs) { return; }; - if query_file_paths.len() < 1 { + if query_file_paths.is_empty() { return; } // File to query @@ -2771,7 +2762,7 @@ async fn jv_info(args: InfoArgs) { } } else { // Multi-line output - if histories.len() > 0 { + if !histories.is_empty() { println!(); } for (version, description) in histories { @@ -3003,7 +2994,6 @@ async fn jv_sheet_use(args: SheetUseArgs) { "{}", md(t!("jv.fail.use.sheet_not_exists", name = args.sheet_name)) ); - return; } std::io::ErrorKind::DirectoryNotEmpty => { eprintln!( @@ -3013,7 +3003,6 @@ async fn jv_sheet_use(args: SheetUseArgs) { name = args.sheet_name )) ); - return; } _ => { handle_err(e.into()); @@ -3049,11 +3038,11 @@ async fn jv_sheet_exit(_args: SheetExitArgs) -> Result<(), ()> { return Err(()); } }; - return Ok(()); + Ok(()) } Err(e) => { handle_err(e.into()); - return Err(()); + Err(()) } } } @@ -3398,7 +3387,7 @@ async fn jv_sheet_align(args: SheetAlignArgs) { ); // Suggestion1: Confirm Erased - if align_tasks.erased.len() > 0 { + if !align_tasks.erased.is_empty() { println!( "\n{}", md(t!( @@ -3408,7 +3397,7 @@ async fn jv_sheet_align(args: SheetAlignArgs) { ) } else // Suggestion2: Confirm Lost - if align_tasks.lost.len() > 0 { + if !align_tasks.lost.is_empty() { println!( "\n{}", md(t!( @@ -3418,7 +3407,7 @@ async fn jv_sheet_align(args: SheetAlignArgs) { ) } else // Suggestion3: Confirm Moved - if align_tasks.moved.len() > 0 { + if !align_tasks.moved.is_empty() { println!( "\n{}", md(t!( @@ -3555,9 +3544,8 @@ async fn jv_sheet_align(args: SheetAlignArgs) { Ok(_) => {} Err(e) => { eprintln!("{}", md(t!("jv.fail.write_cfg", error = e.to_string()))); - return; } - }; + } } } // Lost: match or confirm mode @@ -3596,16 +3584,16 @@ async fn jv_sheet_align(args: SheetAlignArgs) { .created .iter() .find(|p| p.0.starts_with(&to)) - .map(|found| found.clone()) + .cloned() .into_iter() .collect(); - if selected_lost_mapping.len() < 1 { + if selected_lost_mapping.is_empty() { eprintln!("{}", md(t!("jv.fail.sheet.align.no_lost_matched"))); return; } - if created_file.len() < 1 { + if created_file.is_empty() { eprintln!("{}", md(t!("jv.fail.sheet.align.no_created_matched"))); return; } @@ -3646,9 +3634,8 @@ async fn jv_sheet_align(args: SheetAlignArgs) { Ok(_) => {} Err(e) => { eprintln!("{}", md(t!("jv.fail.write_cfg", error = e.to_string()))); - return; } - }; + } } } // Erased: confirm mode @@ -3709,7 +3696,6 @@ async fn jv_sheet_align(args: SheetAlignArgs) { return; } }; - return; } } } @@ -3793,7 +3779,7 @@ async fn jv_track(args: TrackFileArgs) { )) ); - if skipped.len() > 0 { + if !skipped.is_empty() { println!( "\n{}", md(t!( @@ -3939,13 +3925,12 @@ async fn get_update_info( ) -> HashMap { let mut result = HashMap::new(); - if files.len() == 1 { - if let (Some(desc), Some(ver)) = (&args.desc, &args.next_version) { - if let Some(file) = files.iter().next() { - result.insert(file.clone(), (ver.clone(), desc.clone())); - return result; - } - } + if files.len() == 1 + && let (Some(desc), Some(ver)) = (&args.desc, &args.next_version) + && let Some(file) = files.iter().next() + { + result.insert(file.clone(), (ver.clone(), desc.clone())); + return result; } if args.work { return start_update_editor(workspace, files, &args).await; @@ -3989,11 +3974,11 @@ async fn start_update_editor( return HashMap::new(); }; // Has unsolved moves, skip - if analyzed.lost.len() > 0 || analyzed.moved.len() > 0 { + if !analyzed.lost.is_empty() || !analyzed.moved.is_empty() { return HashMap::new(); } // No modified, skip - if analyzed.modified.len() < 1 { + if analyzed.modified.is_empty() { return HashMap::new(); } // No sheet, skip @@ -4008,10 +3993,10 @@ async fn start_update_editor( .iter() .filter_map(|file| { if analyzed.modified.contains(file) { - if let Some(mapping_item) = cached_sheet.mapping().get(file) { - if let Some(latest_version) = latest_file_data.file_version(&mapping_item.id) { - return Some((file.clone(), latest_version.clone())); - } + if let Some(mapping_item) = cached_sheet.mapping().get(file) + && let Some(latest_version) = latest_file_data.file_version(&mapping_item.id) + { + return Some((file.clone(), latest_version.clone())); } None } else { @@ -4501,7 +4486,7 @@ async fn jv_change_edit_right( success_hold, success_throw, } => { - if success_hold.len() > 0 && success_throw.len() == 0 { + if !success_hold.is_empty() && success_throw.is_empty() { println!( "{}", md(t!( @@ -4509,7 +4494,7 @@ async fn jv_change_edit_right( num = success_hold.len() )) ) - } else if success_hold.len() == 0 && success_throw.len() > 0 { + } else if success_hold.is_empty() && !success_throw.is_empty() { println!( "{}", md(t!( @@ -4517,7 +4502,7 @@ async fn jv_change_edit_right( num = success_throw.len() )) ) - } else if success_hold.len() > 0 && success_throw.len() > 0 { + } else if !success_hold.is_empty() && !success_throw.is_empty() { println!( "{}", md(t!( @@ -4563,13 +4548,11 @@ async fn jv_move(args: MoveMappingArgs) { let to_pattern = if args.to_mapping_pattern.is_some() { args.to_mapping_pattern.unwrap() + } else if args.erase { + "".to_string() } else { - if args.erase { - "".to_string() - } else { - eprintln!("{}", md(t!("jv.fail.move.no_target_dir"))); - return; - } + eprintln!("{}", md(t!("jv.fail.move.no_target_dir"))); + return; }; let is_to_pattern_a_dir = to_pattern.ends_with('/') || to_pattern.ends_with('\\'); @@ -4946,30 +4929,30 @@ async fn share_see(share_id: String, args: ShareMappingArgs) { return; }; - if let Some(shares) = latest_info.shares_in_my_sheets.get(&sheet_name) { - if let Some(share) = shares.get(&share_id) { - if args.json_output { - let result = SeeShareResult { - share_id: share_id.clone(), - sharer: share.sharer.clone(), - description: share.description.clone(), - mappings: share.mappings.clone(), - }; - print_json(result, args.pretty); - return; - } - - println!( - "{}", - md(t!( - "jv.success.share.content", - share_id = share_id, - sharer = share.sharer, - description = share.description, - mappings = render_share_path_tree(&share.mappings) - )) - ); + if let Some(shares) = latest_info.shares_in_my_sheets.get(&sheet_name) + && let Some(share) = shares.get(&share_id) + { + if args.json_output { + let result = SeeShareResult { + share_id: share_id.clone(), + sharer: share.sharer.clone(), + description: share.description.clone(), + mappings: share.mappings.clone(), + }; + print_json(result, args.pretty); + return; } + + println!( + "{}", + md(t!( + "jv.success.share.content", + share_id = share_id, + sharer = share.sharer, + description = share.description, + mappings = render_share_path_tree(&share.mappings) + )) + ); } } @@ -5175,8 +5158,7 @@ async fn share_out( let contains_in_other_sheet = latest_info .invisible_sheets .iter() - .find(|info| info.sheet_name == to_sheet) - .is_some(); + .any(|info| info.sheet_name == to_sheet); if !contains_in_my_sheet && !contains_in_other_sheet { eprintln!( "{}", @@ -5307,7 +5289,7 @@ async fn start_share_editor( .iter() .map(|p| { if local_sheet.mapping_data(p).is_err() { - format!("# {}", p.display().to_string()) + format!("# {}", p.display()) } else { p.display().to_string() } @@ -5508,7 +5490,7 @@ async fn jv_account_as(user_dir: UserDirectory, args: SetLocalWorkspaceAccountAr return; }; - if let Err(_) = local_cfg.set_current_account(member.id()) { + if local_cfg.set_current_account(member.id()).is_err() { eprintln!("{}", md(t!("jv.fail.account.as"))); return; }; @@ -5981,7 +5963,7 @@ async fn get_globber( } fn get_local_files(current: &PathBuf, items: &mut HashSet) { - if let Ok(entries) = std::fs::read_dir(¤t) { + if let Ok(entries) = std::fs::read_dir(current) { for entry in entries.flatten() { let path = entry.path(); let name = path @@ -5992,10 +5974,8 @@ fn get_local_files(current: &PathBuf, items: &mut HashSet) { if path.is_file() { items.insert(GlobItem::File(name)); - } else if path.is_dir() { - if name != CLIENT_FOLDER_WORKSPACE_ROOT_NAME { - items.insert(GlobItem::Directory(name)); - } + } else if path.is_dir() && name != CLIENT_FOLDER_WORKSPACE_ROOT_NAME { + items.insert(GlobItem::Directory(name)); } } } @@ -6137,12 +6117,11 @@ fn mapping_names_here( while let Some(parent) = current.parent() { if parent == relative_path { // This is a parent directory, not the file itself - if current != f.as_path() { - if let Some(dir_name) = current.file_name() { - if let Some(dir_str) = dir_name.to_str() { - dirs_set.insert(format!("{}/", dir_str)); - } - } + if current != f.as_path() + && let Some(dir_name) = current.file_name() + && let Some(dir_str) = dir_name.to_str() + { + dirs_set.insert(format!("{}/", dir_str)); } break; } diff --git a/src/bin/jvii.rs b/src/bin/jvii.rs index fbc3ed9..fbd7139 100644 --- a/src/bin/jvii.rs +++ b/src/bin/jvii.rs @@ -85,6 +85,7 @@ impl Editor { }) } + #[allow(clippy::explicit_counter_loop)] fn show_message(&mut self, message: &str, stdout: &mut io::Stdout) -> io::Result<()> { let (width, height) = self.terminal_size; let message_line = height - 2; @@ -100,18 +101,18 @@ impl Editor { let mut _chars_count = 0; let mut current_width = 0; let mut byte_pos = 0; + for c in message.chars() { let char_width = if c.is_ascii() { 1 } else { 2 }; if current_width + char_width > width as usize { break; } current_width += char_width; - _chars_count += 1; byte_pos += c.len_utf8(); } &message[..byte_pos] } else { - &message + message }; stdout.queue(Print(display_message))?; stdout.queue(style::ResetColor)?; @@ -253,6 +254,7 @@ impl Editor { self.modified = true; } + #[allow(clippy::explicit_counter_loop)] fn render(&self, stdout: &mut io::Stdout) -> io::Result<()> { // Clear screen stdout.queue(Clear(ClearType::All))?; diff --git a/src/bin/jvn.rs b/src/bin/jvn.rs index 48b90c5..9041bb9 100644 --- a/src/bin/jvn.rs +++ b/src/bin/jvn.rs @@ -112,7 +112,7 @@ async fn main() { } // Handle help when no arguments provided - if args.len() < 1 && help { + if args.is_empty() && help { warn!("{}", t!("verbose.no_arguments")); helpdoc_viewer::display_with_lang(DEFAULT_HELPDOC, &lang).await; exit(1); @@ -194,7 +194,7 @@ async fn main() { handle_no_matching_command_error(args); } CmdProcessError::ParseError(help) => { - if help.trim().len() < 1 { + if help.trim().is_empty() { eprintln!("{}", md(t!("process_error.parse_error"))); } else { eprintln!("{}", help) @@ -221,11 +221,10 @@ async fn main() { let r = render_result.deref(); if !r.is_empty() { print!("{}", r); - if let Err(e) = io::stdout().flush().await { - if !no_error_logs { + if let Err(e) = io::stdout().flush().await + && !no_error_logs { display_io_error(e); } - } } } } @@ -273,7 +272,7 @@ fn handle_no_matching_command_error(args: Vec) { similar_nodes.push(node); } } - if similar_nodes.len() < 1 { + if similar_nodes.is_empty() { eprintln!("{}", md(t!("process_error.no_matching_command"))); } else { eprintln!( diff --git a/src/bin/jvn_comp.rs b/src/bin/jvn_comp.rs index ea9aaa8..546beda 100644 --- a/src/bin/jvn_comp.rs +++ b/src/bin/jvn_comp.rs @@ -14,7 +14,7 @@ use jvcli::systems::{ use log::debug; use log::{LevelFilter, error, trace}; -const GLOBAL_FLAGS: &[&'static str] = &[ +const GLOBAL_FLAGS: &[&str] = &[ "--confirm", "-C", "--help", @@ -31,7 +31,7 @@ const GLOBAL_FLAGS: &[&'static str] = &[ "-v", ]; -const LANGUAGES: [&'static str; 2] = ["en", "zh-CN"]; +const LANGUAGES: [&str; 2] = ["en", "zh-CN"]; fn main() { // If not in release mode, initialize env_logger to capture logs @@ -140,9 +140,7 @@ fn comp(ctx: &CompletionContext) -> Option> { None => trace!("No completions matched."), } - let Some(match_node) = match_node else { - return None; - }; + let match_node = match_node?; match_comp(match_node, ctx.clone()) } @@ -188,10 +186,11 @@ fn try_comp_cmd_nodes(ctx: &CompletionContext) -> Option> { if input_path.len() == 1 && !ctx.current_word.is_empty() { for node in &cmd_nodes { let node_parts: Vec<&str> = node.split(' ').collect(); - if !node_parts.is_empty() && node_parts[0].starts_with(current_word) { - if !suggestions.contains(&node_parts[0].to_string()) { - suggestions.push(node_parts[0].to_string()); - } + if !node_parts.is_empty() + && node_parts[0].starts_with(current_word) + && !suggestions.contains(&node_parts[0].to_string()) + { + suggestions.push(node_parts[0].to_string()); } } @@ -233,11 +232,9 @@ fn try_comp_cmd_nodes(ctx: &CompletionContext) -> Option> { matches = false; break; } - } else { - if input_path[i] != node_parts[i] { - matches = false; - break; - } + } else if input_path[i] != node_parts[i] { + matches = false; + break; } } diff --git a/src/bin/jvv.rs b/src/bin/jvv.rs index 4872679..057e04c 100644 --- a/src/bin/jvv.rs +++ b/src/bin/jvv.rs @@ -1,3 +1,5 @@ +#![allow(clippy::all)] + // // // ████████ ████████ diff --git a/src/cmds/cmd/helpdoc.rs b/src/cmds/cmd/helpdoc.rs index 74f4c7e..f4c7acf 100644 --- a/src/cmds/cmd/helpdoc.rs +++ b/src/cmds/cmd/helpdoc.rs @@ -38,7 +38,7 @@ async fn collect(_args: &Arg, _ctx: &JVCommandContext) -> Result Result { - helpdoc_viewer::display_with_lang(&input.name.as_str(), &input.lang.as_str()).await; + helpdoc_viewer::display_with_lang(input.name.as_str(), input.lang.as_str()).await; cmd_output!(JVNoneOutput => JVNoneOutput) } diff --git a/src/cmds/cmd/sheetdump.rs b/src/cmds/cmd/sheetdump.rs index badb8fc..6c971fe 100644 --- a/src/cmds/cmd/sheetdump.rs +++ b/src/cmds/cmd/sheetdump.rs @@ -57,7 +57,7 @@ async fn collect(args: &Arg, ctx: &JVCommandContext) -> Result CmdPrepareError::Io(error), })?; - Ok(Collect { sheet: sheet }) + Ok(Collect { sheet }) } #[exec] diff --git a/src/cmds/cmd/sheetedit.rs b/src/cmds/cmd/sheetedit.rs index 8a18ae6..85cb616 100644 --- a/src/cmds/cmd/sheetedit.rs +++ b/src/cmds/cmd/sheetedit.rs @@ -22,7 +22,7 @@ use cmd_system_macros::exec; use just_enough_vcs::system::sheet_system::{mapping::LocalMapping, sheet::SheetData}; use just_fmt::fmt_path::{PathFormatError, fmt_path}; use rust_i18n::t; -use std::{borrow::Cow, path::PathBuf}; +use std::{borrow::Cow, path::Path}; use tokio::fs::create_dir_all; pub struct JVSheeteditCommand; @@ -58,10 +58,10 @@ async fn collect(args: &Arg, ctx: &JVCommandContext) -> Result tokio::fs::read(stdin_path) .await - .map_err(|e| CmdPrepareError::Io(e))?, + .map_err(CmdPrepareError::Io)?, (Some(file_path), None) => tokio::fs::read(file_path) .await - .map_err(|e| CmdPrepareError::Io(e))?, + .map_err(CmdPrepareError::Io)?, (None, None) => return early_cmd_output!(JVNoneOutput => JVNoneOutput), }; Ok(Collect { data }) @@ -95,7 +95,7 @@ async fn exec(input: In, collect: Collect) -> Result cmd_output!(JVNoneOutput => JVNoneOutput {}) } -fn build_template(file: &PathBuf, mappings: Vec) -> Cow<'static, str> { +fn build_template(file: &Path, mappings: Vec) -> Cow<'static, str> { let mapping_table = render_pretty_mappings(&mappings); let template = t!( "sheetedit.editor", @@ -121,13 +121,12 @@ fn render_pretty_mappings(mappings: &Vec) -> String { let mapping_str = mapping .to_string() .split(" ") - .into_iter() .map(|s| s.to_string()) .collect::>(); table.push_item(vec![ format!( " {} ", - mapping_str.get(0).unwrap_or(&String::default()) + mapping_str.first().unwrap_or(&String::default()) ), // Mapping format!("{} ", mapping_str.get(1).unwrap_or(&String::default())), // => & == format!("{} ", mapping_str.get(2).unwrap_or(&String::default())), // Index diff --git a/src/cmds/cmd/workspace_alias.rs b/src/cmds/cmd/workspace_alias.rs index 1c38bdf..b2997d9 100644 --- a/src/cmds/cmd/workspace_alias.rs +++ b/src/cmds/cmd/workspace_alias.rs @@ -45,7 +45,7 @@ async fn prepare(args: &Arg, _ctx: &JVCommandContext) -> Result Result "Alias query result - local: {}, remote: {:?}", index, remote ); - cmd_output!(JVAliasQueryOutput => JVAliasQueryOutput { local: index, remote: remote }) + cmd_output!(JVAliasQueryOutput => JVAliasQueryOutput { local: index, remote }) } _ => { trace!("No alias query requested or no index source available"); diff --git a/src/cmds/comp/workspace_alias.rs b/src/cmds/comp/workspace_alias.rs index 0fd4d23..5efabfa 100644 --- a/src/cmds/comp/workspace_alias.rs +++ b/src/cmds/comp/workspace_alias.rs @@ -21,5 +21,5 @@ pub fn comp(ctx: CompletionContext) -> Option> { return Some(vec![]); } - return None; + None } diff --git a/src/cmds/comp/workspace_sheet.rs b/src/cmds/comp/workspace_sheet.rs index e9d5983..985fe43 100644 --- a/src/cmds/comp/workspace_sheet.rs +++ b/src/cmds/comp/workspace_sheet.rs @@ -7,13 +7,11 @@ pub fn comp(ctx: CompletionContext) -> Option> { return None; } - if ctx.all_words.contains(&"--list-all".to_string()) - || ctx.all_words.contains(&"-A".to_string()) - { - if ctx.all_words.len() > 4 { + if (ctx.all_words.contains(&"--list-all".to_string()) + || ctx.all_words.contains(&"-A".to_string())) + && ctx.all_words.len() > 4 { return None; } - } if ctx.current_word.starts_with('-') { return Some(string_vec![ diff --git a/src/cmds/renderer/mappings_pretty.rs b/src/cmds/renderer/mappings_pretty.rs index 6431302..93a37b5 100644 --- a/src/cmds/renderer/mappings_pretty.rs +++ b/src/cmds/renderer/mappings_pretty.rs @@ -14,7 +14,7 @@ use crate::{ pub async fn render(data: &JVMappingsPrettyOutput) -> Result { let mut r = JVRenderResult::default(); let mappings = &data.mappings; - r_println!(r, "{}", render_pretty_mappings(&mappings)); + r_println!(r, "{}", render_pretty_mappings(mappings)); Ok(r) } @@ -36,7 +36,6 @@ fn render_pretty_mappings(mappings: &Vec) -> String { let mapping_str = mapping .to_string() .split(" ") - .into_iter() .map(|s| s.to_string()) .collect::>(); table.push_item(vec![ @@ -45,8 +44,7 @@ fn render_pretty_mappings(mappings: &Vec) -> String { // Mapping format!( " | {} ", - mapping_str - .get(0) + mapping_str.first() .unwrap_or(&String::default()) .bright_cyan() ), diff --git a/src/systems/cmd/macros.rs b/src/systems/cmd/macros.rs index 9e2446b..0502a26 100644 --- a/src/systems/cmd/macros.rs +++ b/src/systems/cmd/macros.rs @@ -149,7 +149,7 @@ macro_rules! command_template { input: In, collect: Collect, ) -> Result< - crate::systems::cmd::cmd_system::AnyOutput, + $crate::systems::cmd::cmd_system::AnyOutput, $crate::systems::cmd::errors::CmdExecuteError, > { exec(input, collect).await @@ -188,7 +188,7 @@ macro_rules! cmd_output { macro_rules! early_cmd_output { ($t:ty => $v:expr) => {{ let checked_value: $t = $v; - Err(crate::systems::cmd::errors::CmdPrepareError::EarlyOutput(( + Err($crate::systems::cmd::errors::CmdPrepareError::EarlyOutput(( Box::new(checked_value) as Box, std::any::TypeId::of::<$t>(), ))) diff --git a/src/systems/cmd/processer.rs b/src/systems/cmd/processer.rs index aa494bb..2b66eef 100644 --- a/src/systems/cmd/processer.rs +++ b/src/systems/cmd/processer.rs @@ -8,7 +8,7 @@ use crate::systems::cmd::errors::CmdProcessError; use crate::systems::render::renderer::JVRenderResult; pub async fn jv_cmd_process( - args: &Vec, + args: &[String], ctx: JVCommandContext, renderer_override: String, ) -> Result { @@ -22,7 +22,7 @@ pub async fn jv_cmd_process( } async fn process( - args: &Vec, + args: &[String], ctx: JVCommandContext, renderer_override: String, ) -> Result { @@ -48,7 +48,7 @@ async fn process( 0 => { // No matching node found error!("{}", t!("verbose.cmd_match_no_node")); - return Err(CmdProcessError::NoMatchingCommand); + Err(CmdProcessError::NoMatchingCommand) } 1 => { let matched_prefix = matching_nodes[0]; @@ -60,7 +60,7 @@ async fn process( ); let prefix_len = matched_prefix.split_whitespace().count(); - let trimmed_args: Vec = args.into_iter().cloned().skip(prefix_len).collect(); + let trimmed_args: Vec = args.iter().skip(prefix_len).cloned().collect(); return jv_cmd_process_node(matched_prefix, trimmed_args, ctx, renderer_override).await; } _ => { @@ -84,7 +84,7 @@ async fn process( ); let prefix_len = matched_prefix.split_whitespace().count(); - let trimmed_args: Vec = args.into_iter().cloned().skip(prefix_len).collect(); + let trimmed_args: Vec = args.iter().skip(prefix_len).cloned().collect(); return jv_cmd_process_node(matched_prefix, trimmed_args, ctx, renderer_override).await; } } diff --git a/src/systems/helpdoc/helpdoc_viewer.rs b/src/systems/helpdoc/helpdoc_viewer.rs index 560b827..db7f2c6 100644 --- a/src/systems/helpdoc/helpdoc_viewer.rs +++ b/src/systems/helpdoc/helpdoc_viewer.rs @@ -251,10 +251,10 @@ impl HelpdocViewer { while !should_exit { self.draw()?; - if event::poll(std::time::Duration::from_millis(100))? { - if let Event::Key(key) = event::read()? { - should_exit = self.handle_key(key); - } + if event::poll(std::time::Duration::from_millis(100))? + && let Event::Key(key) = event::read()? + { + should_exit = self.handle_key(key); } } @@ -330,6 +330,7 @@ impl HelpdocViewer { } /// Recursively draw tree node + #[allow(clippy::too_many_arguments)] fn draw_tree_node( &self, node: &DocTreeNode, @@ -442,8 +443,8 @@ impl HelpdocViewer { } // Display scroll position indicator - if content_lines.len() > height as usize && content_lines.len() > 0 { - let scroll_percent = if content_lines.len() > 0 { + if content_lines.len() > height as usize && !content_lines.is_empty() { + let scroll_percent = if !content_lines.is_empty() { (scroll_pos * 100) / content_lines.len() } else { 0 @@ -580,16 +581,13 @@ impl HelpdocViewer { /// Select current item fn select_item(&mut self) { - match self.focus { - FocusArea::Tree => { - // Update current document to the one selected in tree view - if let Some(doc) = self.doc_tree.flat_docs.get(self.tree_selection_index) { - self.current_doc = doc.clone(); - } - // Switch focus to content area - self.focus = FocusArea::Content; + if self.focus == FocusArea::Tree { + // Update current document to the one selected in tree view + if let Some(doc) = self.doc_tree.flat_docs.get(self.tree_selection_index) { + self.current_doc = doc.clone(); } - _ => {} + // Switch focus to content area + self.focus = FocusArea::Content; } } diff --git a/src/systems/render/renderer.rs b/src/systems/render/renderer.rs index 13de8c6..1a4029f 100644 --- a/src/systems/render/renderer.rs +++ b/src/systems/render/renderer.rs @@ -20,7 +20,7 @@ pub struct JVRenderResult { impl Display for JVRenderResult { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}\n", self.render_text.trim()) + writeln!(f, "{}", self.render_text.trim()) } } diff --git a/templates/_commands.rs.template b/templates/_commands.rs.template index c11e312..512db2c 100644 --- a/templates/_commands.rs.template +++ b/templates/_commands.rs.template @@ -13,7 +13,7 @@ pub async fn jv_cmd_process_node( >>>>>>>>>> command_match_arms _ => {} } - return Err(CmdProcessError::NoNodeFound(node.to_string())); + Err(CmdProcessError::NoNodeFound(node.to_string())) } /// Get all command nodes diff --git a/tools/build_helper/src/bin/exporter.rs b/tools/build_helper/src/bin/exporter.rs index c20694b..322e890 100644 --- a/tools/build_helper/src/bin/exporter.rs +++ b/tools/build_helper/src/bin/exporter.rs @@ -213,8 +213,8 @@ fn copy_configs() -> Result, std::io::Error> { let mut copy_configs = Vec::new(); - if let Some(copies) = config.get("copies") { - if let Some(tables) = copies.as_table() { + if let Some(copies) = config.get("copies") + && let Some(tables) = copies.as_table() { for (_, table) in tables { if let Some(from) = table.get("from").and_then(|v| v.as_str()) { let to = table.get("to").and_then(|v| v.as_str()).unwrap_or(""); @@ -238,7 +238,6 @@ fn copy_configs() -> Result, std::io::Error> { } } } - } Ok(copy_configs) } diff --git a/utils/src/display/markdown.rs b/utils/src/display/markdown.rs index c50085e..f2fef3b 100644 --- a/utils/src/display/markdown.rs +++ b/utils/src/display/markdown.rs @@ -147,7 +147,7 @@ pub fn markdown(text: impl AsRef) -> String { line_result.push_str(&indent); line_result.push_str(&processed_line); } else { - line_result.push_str(" "); + line_result.push(' '); } if !line_result.is_empty() { @@ -218,8 +218,8 @@ fn process_line(line: &str) -> String { } // Check for color tag start [[color]] - if i + 1 < chars.len() && chars[i] == '[' && chars[i + 1] == '[' { - if let Some(end) = find_tag_end(&chars, i) { + if i + 1 < chars.len() && chars[i] == '[' && chars[i + 1] == '[' + && let Some(end) = find_tag_end(&chars, i) { let tag_content: String = chars[i + 2..end].iter().collect(); // Check if it's a closing tag [[/]] @@ -232,11 +232,10 @@ fn process_line(line: &str) -> String { i = end + 2; continue; } - } // Check for bold **text** - if i + 1 < chars.len() && chars[i] == '*' && chars[i + 1] == '*' { - if let Some(end) = find_matching(&chars, i + 2, "**") { + if i + 1 < chars.len() && chars[i] == '*' && chars[i + 1] == '*' + && let Some(end) = find_matching(&chars, i + 2, "**") { let bold_text: String = chars[i + 2..end].iter().collect(); let mut formatted_text = bold_text.bold().to_string(); apply_color_stack(&mut formatted_text, &color_stack); @@ -244,11 +243,10 @@ fn process_line(line: &str) -> String { i = end + 2; continue; } - } // Check for italic *text* - if chars[i] == '*' { - if let Some(end) = find_matching(&chars, i + 1, "*") { + if chars[i] == '*' + && let Some(end) = find_matching(&chars, i + 1, "*") { let italic_text: String = chars[i + 1..end].iter().collect(); let mut formatted_text = italic_text.italic().to_string(); apply_color_stack(&mut formatted_text, &color_stack); @@ -256,11 +254,10 @@ fn process_line(line: &str) -> String { i = end + 1; continue; } - } // Check for underline _text_ - if chars[i] == '_' { - if let Some(end) = find_matching(&chars, i + 1, "_") { + if chars[i] == '_' + && let Some(end) = find_matching(&chars, i + 1, "_") { let underline_text: String = chars[i + 1..end].iter().collect(); let mut formatted_text = format!("\x1b[4m{}\x1b[0m", underline_text); apply_color_stack(&mut formatted_text, &color_stack); @@ -268,11 +265,10 @@ fn process_line(line: &str) -> String { i = end + 1; continue; } - } // Check for angle-bracketed content - if chars[i] == '<' { - if let Some(end) = find_matching(&chars, i + 1, ">") { + if chars[i] == '<' + && let Some(end) = find_matching(&chars, i + 1, ">") { // Include the angle brackets in the output let angle_text: String = chars[i..=end].iter().collect(); let mut formatted_text = angle_text.cyan().to_string(); @@ -281,11 +277,10 @@ fn process_line(line: &str) -> String { i = end + 1; continue; } - } // Check for inline code `text` - if chars[i] == '`' { - if let Some(end) = find_matching(&chars, i + 1, "`") { + if chars[i] == '`' + && let Some(end) = find_matching(&chars, i + 1, "`") { // Include the backticks in the output let code_text: String = chars[i..=end].iter().collect(); let mut formatted_text = code_text.green().to_string(); @@ -294,7 +289,6 @@ fn process_line(line: &str) -> String { i = end + 1; continue; } - } // Regular character let mut current_char = chars[i].to_string(); diff --git a/utils/src/input/editor.rs b/utils/src/input/editor.rs index aa3e1be..45867e5 100644 --- a/utils/src/input/editor.rs +++ b/utils/src/input/editor.rs @@ -30,10 +30,7 @@ pub async fn input_with_editor_cutsom( let status = Command::new(editor).arg(cache_path).status().await?; if !status.success() { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Editor exited with non-zero status", - )); + return Err(std::io::Error::other("Editor exited with non-zero status")); } // Read the modified content @@ -42,14 +39,7 @@ pub async fn input_with_editor_cutsom( // Remove comment lines and trim let processed_content: String = content .lines() - .filter_map(|line| { - let trimmed = line.trim(); - if trimmed.starts_with(comment_prefix) { - None - } else { - Some(line) - } - }) + .filter(|line| !line.trim().starts_with(comment_prefix)) .collect::>() .join("\n"); diff --git a/utils/src/legacy/display.rs b/utils/src/legacy/display.rs index fc94d90..57f4f5b 100644 --- a/utils/src/legacy/display.rs +++ b/utils/src/legacy/display.rs @@ -1,3 +1,5 @@ +#![allow(clippy::all)] + use colored::*; use just_enough_vcs::lib::data::sheet::SheetMappingMetadata; use std::{ diff --git a/utils/src/legacy/env.rs b/utils/src/legacy/env.rs index 1834cd3..b4ad089 100644 --- a/utils/src/legacy/env.rs +++ b/utils/src/legacy/env.rs @@ -67,10 +67,7 @@ pub fn auto_update_outdate() -> i64 { } match std::env::var("JV_OUTDATED_MINUTES") { - Ok(value) => match value.trim().parse::() { - Ok(num) => num, - Err(_) => -1, - }, + Ok(value) => value.trim().parse::().unwrap_or(-1), Err(_) => -1, } } diff --git a/utils/src/legacy/globber.rs b/utils/src/legacy/globber.rs index 4d722db..b6a3032 100644 --- a/utils/src/legacy/globber.rs +++ b/utils/src/legacy/globber.rs @@ -69,9 +69,7 @@ impl Globber { } }; - let pattern = if pattern.is_empty() { - "*".to_string() - } else if pattern == "." { + let pattern = if pattern.is_empty() || pattern == "." { "*".to_string() } else if pattern.ends_with(SPLIT_STR) { format!("{}*", pattern) @@ -182,7 +180,7 @@ impl> From for Globber { } } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub enum GlobItem { File(String), Directory(String), @@ -207,6 +205,21 @@ impl std::fmt::Display for GlobItem { } } +impl std::hash::Hash for GlobItem { + fn hash(&self, state: &mut H) { + match self { + GlobItem::File(name) => { + state.write_u8(0); + name.hash(state); + } + GlobItem::Directory(name) => { + state.write_u8(1); + name.hash(state); + } + } + } +} + impl Eq for GlobItem {} pub mod constants { diff --git a/utils/src/legacy/input.rs b/utils/src/legacy/input.rs index 95d53cb..501ce69 100644 --- a/utils/src/legacy/input.rs +++ b/utils/src/legacy/input.rs @@ -89,10 +89,7 @@ pub async fn input_with_editor_cutsom( let status = Command::new(editor).arg(cache_path).status().await?; if !status.success() { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Editor exited with non-zero status", - )); + return Err(std::io::Error::other("Editor exited with non-zero status")); } // Read the modified content @@ -101,14 +98,7 @@ pub async fn input_with_editor_cutsom( // Remove comment lines and trim let processed_content: String = content .lines() - .filter_map(|line| { - let trimmed = line.trim(); - if trimmed.starts_with(comment_prefix) { - None - } else { - Some(line) - } - }) + .filter(|line| !line.trim().starts_with(comment_prefix)) .collect::>() .join("\n"); diff --git a/utils/src/legacy/logger.rs b/utils/src/legacy/logger.rs index 1bc96c1..7c18d30 100644 --- a/utils/src/legacy/logger.rs +++ b/utils/src/legacy/logger.rs @@ -79,7 +79,7 @@ pub fn build_env_logger(log_path: impl AsRef, logger_level: LoggerLevel) { builder .format(log_format) - .filter(None, level.clone()) + .filter(None, level) .filter_module("just_enough_vcs", level) .target(combined_target) .init(); -- cgit