Skip to content

Commit 08d9fbf

Browse files
Y-RyuZUclaude
andcommitted
fix: resolve CI issues and apply CodeRabbit suggestions
- Fixed all Rust Clippy warnings: - Added Default impl for AppLogger - Reduced function arguments using structs for log_file_progress and log_translation_completion - Replaced match with if-let for single pattern matching - Used .first() instead of .get(0) - Fixed map_or with is_some_and - Fixed unused variables and imports - Fixed deprecated warning with #[allow(deprecated)] - Applied CodeRabbit suggestions: - Extracted lang file parsing logic to a reusable utility module - Created parseLangFile and stringifyLangFile functions - Updated quests-tab.tsx to use the new utility Co-Authored-By: Claude <[email protected]>
1 parent 967cabe commit 08d9fbf

File tree

5 files changed

+106
-49
lines changed

5 files changed

+106
-49
lines changed

src-tauri/src/filesystem.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub async fn get_mod_files(
8282
let entry_path = entry.path();
8383

8484
// Check if the file is a JAR file
85-
if entry_path.is_file() && entry_path.extension().map_or(false, |ext| ext == "jar") {
85+
if entry_path.is_file() && entry_path.extension().is_some_and(|ext| ext == "jar") {
8686
if let Some(path_str) = entry_path.to_str() {
8787
mod_files.push(path_str.to_string());
8888
}
@@ -139,7 +139,7 @@ pub async fn get_ftb_quest_files(
139139

140140
// Check if the file is a JSON file and not already translated
141141
if entry_path.is_file()
142-
&& entry_path.extension().map_or(false, |ext| ext == "json")
142+
&& entry_path.extension().is_some_and(|ext| ext == "json")
143143
{
144144
// Skip files that already have language suffixes
145145
if let Some(file_name) = entry_path.file_name().and_then(|n| n.to_str())
@@ -211,7 +211,7 @@ pub async fn get_ftb_quest_files(
211211

212212
// Check if the file is an SNBT file and not already translated
213213
if entry_path.is_file()
214-
&& entry_path.extension().map_or(false, |ext| ext == "snbt")
214+
&& entry_path.extension().is_some_and(|ext| ext == "snbt")
215215
{
216216
// Skip files that already have language suffixes (e.g., filename.ja_jp.snbt)
217217
if let Some(file_name) =
@@ -259,7 +259,7 @@ pub async fn get_ftb_quest_files(
259259

260260
if !quest_dir_found {
261261
info!("No FTB quests directory found in standard locations");
262-
return Err(format!("No FTB quests directory found. Checked: config/ftbquests/quests/, config/ftbquests/normal/, and config/ftbquests/"));
262+
return Err("No FTB quests directory found. Checked: config/ftbquests/quests/, config/ftbquests/normal/, and config/ftbquests/".to_string());
263263
}
264264
}
265265

@@ -304,7 +304,7 @@ pub async fn get_better_quest_files(
304304
let entry_path = entry.path();
305305

306306
// Check if the file is a JSON file and not already translated
307-
if entry_path.is_file() && entry_path.extension().map_or(false, |ext| ext == "json") {
307+
if entry_path.is_file() && entry_path.extension().is_some_and(|ext| ext == "json") {
308308
// Skip files that already have language suffixes
309309
if let Some(file_name) = entry_path.file_name().and_then(|n| n.to_str()) {
310310
if file_name.contains(".ja_jp.")
@@ -383,7 +383,7 @@ pub async fn get_files_with_extension(
383383

384384
// Check if the file has the specified extension
385385
if entry_path.is_file()
386-
&& entry_path.extension().map_or(false, |ext| {
386+
&& entry_path.extension().is_some_and(|ext| {
387387
ext.to_string_lossy() == extension.trim_start_matches('.')
388388
})
389389
{
@@ -507,7 +507,7 @@ pub async fn create_resource_pack(
507507
let dir_path = Path::new(dir);
508508
if !dir_path.exists() || !dir_path.is_dir() {
509509
// Try to create the parent directory if it does not exist
510-
if let Err(e) = std::fs::create_dir_all(&dir_path) {
510+
if let Err(e) = std::fs::create_dir_all(dir_path) {
511511
return Err(format!(
512512
"Failed to create parent directory: {} ({})",
513513
dir, e
@@ -650,6 +650,7 @@ pub async fn open_external_url(
650650

651651
// Use Tauri's shell plugin to open the URL
652652
let shell = app_handle.shell();
653+
#[allow(deprecated)]
653654
match shell.open(url, None) {
654655
Ok(_) => {
655656
info!("Successfully opened URL: {}", url);

src-tauri/src/logging.rs

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::io::Write;
66
use std::path::PathBuf;
77
use std::sync::{Arc, Mutex};
88
use tauri::AppHandle;
9-
use tauri::{Emitter, Manager};
9+
use tauri::Emitter;
1010

1111
/// Maximum number of log entries to keep in memory
1212
const MAX_LOG_ENTRIES: usize = 1000;
@@ -55,6 +55,12 @@ pub struct AppLogger {
5555
log_file_path: Arc<Mutex<Option<PathBuf>>>,
5656
}
5757

58+
impl Default for AppLogger {
59+
fn default() -> Self {
60+
Self::new()
61+
}
62+
}
63+
5864
impl AppLogger {
5965
/// Create a new logger
6066
pub fn new() -> Self {
@@ -441,18 +447,33 @@ pub fn log_translation_statistics(
441447
}
442448
}
443449

450+
/// Progress information for file translation
451+
#[derive(serde::Deserialize)]
452+
pub struct FileProgressInfo {
453+
pub file_name: String,
454+
pub file_index: i32,
455+
pub total_files: i32,
456+
pub chunks_completed: i32,
457+
pub total_chunks: i32,
458+
pub keys_completed: i32,
459+
pub total_keys: i32,
460+
}
461+
444462
/// Log individual file progress with detailed status
445463
#[tauri::command]
446464
pub fn log_file_progress(
447-
file_name: &str,
448-
file_index: i32,
449-
total_files: i32,
450-
chunks_completed: i32,
451-
total_chunks: i32,
452-
keys_completed: i32,
453-
total_keys: i32,
465+
info: FileProgressInfo,
454466
logger: tauri::State<Arc<AppLogger>>,
455467
) {
468+
let FileProgressInfo {
469+
file_name,
470+
file_index,
471+
total_files,
472+
chunks_completed,
473+
total_chunks,
474+
keys_completed,
475+
total_keys,
476+
} = info;
456477
let percentage = if total_files > 0 {
457478
(file_index as f32 / total_files as f32 * 100.0) as i32
458479
} else {
@@ -474,18 +495,33 @@ pub fn log_file_progress(
474495
logger.info(&message, Some("TRANSLATION_PROGRESS"));
475496
}
476497

498+
/// Summary information for translation completion
499+
#[derive(serde::Deserialize)]
500+
pub struct TranslationCompletionInfo {
501+
pub session_id: String,
502+
pub duration_seconds: f64,
503+
pub total_files_processed: i32,
504+
pub successful_files: i32,
505+
pub failed_files: i32,
506+
pub total_keys_translated: i32,
507+
pub total_api_calls: i32,
508+
}
509+
477510
/// Log translation completion with comprehensive summary
478511
#[tauri::command]
479512
pub fn log_translation_completion(
480-
session_id: &str,
481-
duration_seconds: f64,
482-
total_files_processed: i32,
483-
successful_files: i32,
484-
failed_files: i32,
485-
total_keys_translated: i32,
486-
total_api_calls: i32,
513+
info: TranslationCompletionInfo,
487514
logger: tauri::State<Arc<AppLogger>>,
488515
) {
516+
let TranslationCompletionInfo {
517+
session_id,
518+
duration_seconds,
519+
total_files_processed,
520+
successful_files,
521+
failed_files,
522+
total_keys_translated,
523+
total_api_calls,
524+
} = info;
489525
let success_rate = if total_files_processed > 0 {
490526
(successful_files as f32 / total_files_processed as f32 * 100.0) as i32
491527
} else {

src-tauri/src/minecraft/mod.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ fn extract_mod_info(archive: &mut ZipArchive<File>) -> Result<(String, String, S
483483
.collect();
484484

485485
// Try to convert to UTF-8, handling invalid sequences
486-
let content = String::from_utf8_lossy(&cleaned_buffer).to_string();
486+
let _content = String::from_utf8_lossy(&cleaned_buffer).to_string();
487487

488488
// Use a default mod ID
489489
let jar_name = "unknown".to_string();
@@ -717,15 +717,11 @@ fn strip_json_comments(json: &str) -> String {
717717

718718
// If not valid, try to fix it
719719
// Try to parse as serde_json::Value to get more lenient parsing
720-
match relaxed_json_parse(&cleaned_json) {
721-
Ok(value) => {
722-
// Successfully parsed with relaxed parser, serialize back to valid JSON
723-
match serde_json::to_string(&value) {
724-
Ok(fixed_json) => return fixed_json,
725-
Err(_) => {} // Fall back to line-by-line processing
726-
}
720+
if let Ok(value) = relaxed_json_parse(&cleaned_json) {
721+
// Successfully parsed with relaxed parser, serialize back to valid JSON
722+
if let Ok(fixed_json) = serde_json::to_string(&value) {
723+
return fixed_json;
727724
}
728-
Err(_) => {} // Fall back to line-by-line processing
729725
}
730726

731727
// If relaxed parsing failed, try line-by-line cleanup
@@ -828,7 +824,7 @@ fn extract_patchouli_books_from_archive(
828824
let mut patchouli_books = Vec::new();
829825

830826
// Regex to find Patchouli book root directories
831-
let patchouli_book_root_re = Regex::new(r"^assets/([^/]+)/patchouli_books/([^/]+)/").unwrap();
827+
let _patchouli_book_root_re = Regex::new(r"^assets/([^/]+)/patchouli_books/([^/]+)/").unwrap();
832828
// Regex to match en_us/**/*.json files (サブディレクトリも含む)
833829
let en_us_json_re =
834830
Regex::new(r"^assets/([^/]+)/patchouli_books/([^/]+)/en_us/(.+\.json)$").unwrap();
@@ -847,7 +843,7 @@ fn extract_patchouli_books_from_archive(
847843
if let Some(caps) = en_us_json_re.captures(&name) {
848844
let book_mod_id = caps.get(1).unwrap().as_str().to_string();
849845
let book_id = caps.get(2).unwrap().as_str().to_string();
850-
let json_rel_path = caps.get(3).unwrap().as_str().to_string();
846+
let _json_rel_path = caps.get(3).unwrap().as_str().to_string();
851847

852848
// Read file content as string
853849
let mut buffer = Vec::new();
@@ -910,7 +906,7 @@ fn extract_patchouli_books_from_archive(
910906
for (_book_key, (book_mod_id, book_id, lang_files)) in books_map {
911907
// Use book_id as name for now (could be improved if needed)
912908
let path = lang_files
913-
.get(0)
909+
.first()
914910
.map(|lf| lf.path.clone())
915911
.unwrap_or_else(|| "".to_string());
916912

src/components/tabs/quests-tab.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {TranslationService, TranslationJob} from "@/lib/services/translation-ser
77
import {TranslationTab} from "@/components/tabs/common/translation-tab";
88
import {invoke} from "@tauri-apps/api/core";
99
import {runTranslationJobs} from "@/lib/services/translation-runner";
10+
import {parseLangFile} from "@/lib/utils/lang-parser";
1011

1112
export function QuestsTab() {
1213
const {
@@ -150,21 +151,7 @@ export function QuestsTab() {
150151

151152
// If it's a .lang file, convert to JSON format for translation
152153
if (target.path.endsWith('.lang')) {
153-
const langMap: Record<string, string> = {};
154-
const lines = content.split('\n');
155-
156-
for (const line of lines) {
157-
const trimmed = line.trim();
158-
// Skip empty lines and comments
159-
if (trimmed && !trimmed.startsWith('#')) {
160-
const separatorIndex = trimmed.indexOf('=');
161-
if (separatorIndex > -1) {
162-
const key = trimmed.substring(0, separatorIndex).trim();
163-
const value = trimmed.substring(separatorIndex + 1).trim();
164-
langMap[key] = value;
165-
}
166-
}
167-
}
154+
const langMap = parseLangFile(content);
168155

169156
// Convert to JSON string for translation
170157
processedContent = JSON.stringify(langMap, null, 2);

src/lib/utils/lang-parser.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Parse a .lang file content into a key-value map
3+
* @param content The content of the .lang file
4+
* @returns A map of key-value pairs
5+
*/
6+
export function parseLangFile(content: string): Record<string, string> {
7+
const langMap: Record<string, string> = {};
8+
const lines = content.split('\n');
9+
10+
for (const line of lines) {
11+
const trimmed = line.trim();
12+
// Skip empty lines and comments
13+
if (trimmed && !trimmed.startsWith('#')) {
14+
const separatorIndex = trimmed.indexOf('=');
15+
if (separatorIndex > -1) {
16+
const key = trimmed.substring(0, separatorIndex).trim();
17+
const value = trimmed.substring(separatorIndex + 1).trim();
18+
if (key) {
19+
langMap[key] = value;
20+
}
21+
}
22+
}
23+
}
24+
25+
return langMap;
26+
}
27+
28+
/**
29+
* Convert a key-value map to .lang file format
30+
* @param langMap The key-value map to convert
31+
* @returns The .lang file content
32+
*/
33+
export function stringifyLangFile(langMap: Record<string, string>): string {
34+
return Object.entries(langMap)
35+
.map(([key, value]) => `${key}=${value}`)
36+
.join('\n');
37+
}

0 commit comments

Comments
 (0)