mod files; mod history; mod metadata; mod settings; use renamr_core::format::ExpressionFormat; use renamr_core::matching::{self, EpisodeGuess, MovieGuess}; use renamr_core::rename::{self, RenamePlanItem, RenameResult}; use renamr_core::string_bindings; use std::collections::HashMap; use tauri::AppHandle; /// Renders a naming-scheme expression against a set of binding values. /// This is the Tauri-facing entry point into the core format engine, used by the /// rename-preview panel in the UI so users see live results as they edit a pattern. #[tauri::command] fn render_expression(expression: String, bindings: HashMap) -> Result { let compiled = ExpressionFormat::compile(&expression).map_err(|e| e.to_string())?; compiled .format(&string_bindings(bindings)) .map_err(|e| e.to_string()) } /// Guesses a season/episode number pair (and series name) from a filename using local /// regex patterns only - no network calls, no metadata lookup. Returns `None` when the /// filename doesn't carry a recognizable season/episode marker (movies, already-clean /// names, etc). #[tauri::command] fn guess_episode(filename: String) -> Option { matching::guess_episode(&filename) } /// Guesses a movie title (and release year, if present) from a filename using local /// regex/heuristic patterns only - no network calls. Callers should try /// `guess_episode` first and only fall back to this when it returns `None`; see /// `matching::guess_movie` for why. #[tauri::command] fn guess_movie(filename: String) -> Option { matching::guess_movie(&filename) } /// Executes a batch of planned on-disk renames (optionally moving files into /// subfolders - see `renamr_core::rename`; conflicting targets are always skipped, /// never overwritten). The UI is expected to have already shown the user the full /// old-path/new-path plan and gotten explicit confirmation before calling this. /// Runs off the main thread since real filesystem I/O shouldn't block the UI. /// /// Every successfully-renamed item is recorded to the rename history log afterward /// (see `history::record_batch`) so it can be undone later from the History panel. #[tauri::command] async fn execute_rename(app: AppHandle, items: Vec) -> Vec { let results = tauri::async_runtime::spawn_blocking(move || rename::execute_renames(&items)) .await .unwrap_or_default(); history::record_batch(&app, &results); results } #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_dialog::init()) .invoke_handler(tauri::generate_handler![ render_expression, guess_episode, guess_movie, execute_rename, metadata::fetch_metadata, metadata::fetch_movie_metadata, settings::get_tmdb_token, settings::save_tmdb_token, history::list_rename_history, history::undo_rename_batch, files::pick_files, files::pick_folder, files::expand_dropped_paths, ]) .run(tauri::generate_context!()) .expect("error while running Renamr"); }