fix: 修复 Rust lint 警告

修复了以下 clippy 警告:
- 移除未使用的 imports
- 修复未使用的变量(添加 _ 前缀)
- 移除不必要的 mut 关键字
- 为未使用的函数添加 #[allow(dead_code)] 注解
- 使用新的格式化字符串语法(uninlined_format_args)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
coso
2025-12-14 18:40:43 +08:00
co-authored by Claude Sonnet 4.5
parent ad905dc251
commit dd8d58a157
21 changed files with 104 additions and 92 deletions
+2 -1
View File
@@ -11,7 +11,8 @@
"Bash(tree:*)",
"Bash(find:*)",
"Bash(cargo check:*)",
"Bash(rm:*)"
"Bash(rm:*)",
"Bash(cargo clippy:*)"
],
"deny": [],
"ask": []
+1 -1
View File
@@ -2873,7 +2873,7 @@ dependencies = [
[[package]]
name = "proxycast"
version = "0.5.0"
version = "0.5.1"
dependencies = [
"async-stream",
"axum",
+4 -4
View File
@@ -61,7 +61,7 @@ pub fn get_config_dir_path(app_type: String) -> Result<String, String> {
}
#[tauri::command]
pub async fn open_config_folder(handle: AppHandle, app_type: String) -> Result<bool, String> {
pub async fn open_config_folder(_handle: AppHandle, app_type: String) -> Result<bool, String> {
let app = app_type.parse::<AppType>().map_err(|e| e.to_string())?;
let config_dir = get_config_dir(&app).ok_or("Cannot determine config directory")?;
@@ -175,7 +175,7 @@ pub async fn get_auto_launch_status(app: AppHandle) -> Result<bool, String> {
let autostart_manager = app.autolaunch();
autostart_manager
.is_enabled()
.map_err(|e| format!("Failed to get autostart status: {}", e))
.map_err(|e| format!("Failed to get autostart status: {e}"))
}
#[tauri::command]
@@ -185,11 +185,11 @@ pub async fn set_auto_launch(app: AppHandle, enabled: bool) -> Result<bool, Stri
if enabled {
autostart_manager
.enable()
.map_err(|e| format!("Failed to enable autostart: {}", e))?;
.map_err(|e| format!("Failed to enable autostart: {e}"))?;
} else {
autostart_manager
.disable()
.map_err(|e| format!("Failed to disable autostart: {}", e))?;
.map_err(|e| format!("Failed to disable autostart: {e}"))?;
}
Ok(enabled)
+5 -4
View File
@@ -25,7 +25,7 @@ impl OAuthProvider {
"kiro" => Ok(OAuthProvider::Kiro),
"gemini" => Ok(OAuthProvider::Gemini),
"qwen" => Ok(OAuthProvider::Qwen),
_ => Err(format!("Unknown provider: {}", s)),
_ => Err(format!("Unknown provider: {s}")),
}
}
@@ -399,9 +399,10 @@ pub async fn check_and_reload_oauth_credentials(
match result {
Ok(_) => {
logs.write()
.await
.add("info", &format!("[{display_name}][自动检测] 凭证重新加载成功"));
logs.write().await.add(
"info",
&format!("[{display_name}][自动检测] 凭证重新加载成功"),
);
Ok(CheckResult {
changed: true,
new_hash,
+3 -14
View File
@@ -42,30 +42,19 @@ pub fn update_prompt(db: State<'_, DbConnection>, prompt: Prompt) -> Result<(),
/// Delete a prompt
#[tauri::command]
pub fn delete_prompt(
db: State<'_, DbConnection>,
app: String,
id: String,
) -> Result<(), String> {
pub fn delete_prompt(db: State<'_, DbConnection>, app: String, id: String) -> Result<(), String> {
PromptService::delete(&db, &app, &id)
}
/// Enable a prompt and sync to live file
#[tauri::command]
pub fn enable_prompt(
db: State<'_, DbConnection>,
app: String,
id: String,
) -> Result<(), String> {
pub fn enable_prompt(db: State<'_, DbConnection>, app: String, id: String) -> Result<(), String> {
PromptService::enable(&db, &app, &id)
}
/// Import prompt from live file
#[tauri::command]
pub fn import_prompt_from_file(
db: State<'_, DbConnection>,
app: String,
) -> Result<String, String> {
pub fn import_prompt_from_file(db: State<'_, DbConnection>, app: String) -> Result<String, String> {
PromptService::import_from_file(&db, &app)
}
+2 -3
View File
@@ -90,13 +90,12 @@ impl McpDao {
"gemini" => "enabled_gemini",
_ => {
return Err(rusqlite::Error::InvalidParameterName(format!(
"Invalid app_type: {}",
app_type
"Invalid app_type: {app_type}"
)))
}
};
let sql = format!("UPDATE mcp_servers SET {} = ? WHERE id = ?", column);
let sql = format!("UPDATE mcp_servers SET {column} = ? WHERE id = ?");
conn.execute(&sql, params![if enabled { 1 } else { 0 }, id])?;
Ok(())
}
-4
View File
@@ -1,7 +1,3 @@
pub mod mcp;
pub mod prompts;
pub mod providers;
pub use mcp::McpDao;
pub use prompts::PromptDao;
pub use providers::ProviderDao;
+5 -1
View File
@@ -167,7 +167,10 @@ impl PromptDao {
/// Disable all prompts for an app type
pub fn disable_all(conn: &Connection, app_type: &str) -> Result<(), rusqlite::Error> {
conn.execute("UPDATE prompts SET enabled = 0 WHERE app_type = ?", [app_type])?;
conn.execute(
"UPDATE prompts SET enabled = 0 WHERE app_type = ?",
[app_type],
)?;
Ok(())
}
@@ -184,6 +187,7 @@ impl PromptDao {
}
// Legacy method for compatibility
#[allow(dead_code)]
pub fn set_current(conn: &Connection, app_type: &str, id: &str) -> Result<(), rusqlite::Error> {
Self::enable(conn, app_type, id)
}
+2 -2
View File
@@ -1,8 +1,8 @@
use rusqlite::Connection;
use serde_json::Value;
use std::path::PathBuf;
/// 从旧的 JSON 配置迁移数据到 SQLite
#[allow(dead_code)]
pub fn migrate_from_json(
conn: &Connection,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
@@ -26,7 +26,7 @@ pub fn migrate_from_json(
if config_path.exists() {
let content = std::fs::read_to_string(&config_path)?;
let config: Value = serde_json::from_str(&content)?;
let _config: Value = serde_json::from_str(&content)?;
// TODO: 解析旧配置并插入到数据库
// 这里需要根据实际的旧配置格式来实现
+4 -1
View File
@@ -53,7 +53,10 @@ pub fn create_tables(conn: &Connection) -> Result<(), rusqlite::Error> {
)?;
// Migration: rename is_current to enabled if old column exists
let _ = conn.execute("ALTER TABLE prompts RENAME COLUMN is_current TO enabled", []);
let _ = conn.execute(
"ALTER TABLE prompts RENAME COLUMN is_current TO enabled",
[],
);
// Migration: add updated_at column if it doesn't exist
let _ = conn.execute("ALTER TABLE prompts ADD COLUMN updated_at INTEGER", []);
+1 -1
View File
@@ -29,7 +29,7 @@ impl std::str::FromStr for AppType {
"claude" => Ok(AppType::Claude),
"codex" => Ok(AppType::Codex),
"gemini" => Ok(AppType::Gemini),
_ => Err(format!("Invalid app type: {}", s)),
_ => Err(format!("Invalid app type: {s}")),
}
}
}
+1
View File
@@ -21,6 +21,7 @@ pub struct McpServer {
}
impl McpServer {
#[allow(dead_code)]
pub fn new(id: String, name: String, server_config: Value) -> Self {
Self {
id,
+1
View File
@@ -18,6 +18,7 @@ pub struct Prompt {
}
impl Prompt {
#[allow(dead_code)]
pub fn new(id: String, app_type: String, name: String, content: String) -> Self {
let now = chrono::Utc::now().timestamp();
Self {
+1
View File
@@ -24,6 +24,7 @@ pub struct Provider {
}
impl Provider {
#[allow(dead_code)]
pub fn new(id: String, app_type: String, name: String, settings_config: Value) -> Self {
Self {
id,
+16 -10
View File
@@ -46,7 +46,11 @@ fn sync_claude_settings(
};
// Merge env variables into settings
if let Some(env_obj) = provider.settings_config.get("env").and_then(|v| v.as_object()) {
if let Some(env_obj) = provider
.settings_config
.get("env")
.and_then(|v| v.as_object())
{
let settings_obj = settings.as_object_mut().ok_or("Invalid settings format")?;
// Ensure env object exists
@@ -72,9 +76,7 @@ fn sync_claude_settings(
}
/// Sync Codex config to ~/.codex/auth.json and ~/.codex/config.toml
fn sync_codex_config(
provider: &Provider,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
fn sync_codex_config(provider: &Provider) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
let codex_dir = home.join(".codex");
@@ -100,9 +102,7 @@ fn sync_codex_config(
}
/// Sync Gemini config to ~/.gemini/.env and ~/.gemini/settings.json
fn sync_gemini_config(
provider: &Provider,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
fn sync_gemini_config(provider: &Provider) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
let gemini_dir = home.join(".gemini");
@@ -110,7 +110,11 @@ fn sync_gemini_config(
std::fs::create_dir_all(&gemini_dir)?;
// Write .env file
if let Some(env_obj) = provider.settings_config.get("env").and_then(|v| v.as_object()) {
if let Some(env_obj) = provider
.settings_config
.get("env")
.and_then(|v| v.as_object())
{
let env_path = gemini_dir.join(".env");
let mut content = String::new();
@@ -118,7 +122,7 @@ fn sync_gemini_config(
if let Some(val) = value.as_str() {
// Only write non-empty values
if !val.is_empty() {
content.push_str(&format!("{}={}\n", key, val));
content.push_str(&format!("{key}={val}\n"));
}
}
}
@@ -157,7 +161,9 @@ fn sync_gemini_config(
}
/// Read current live settings for an app type
pub fn read_live_settings(app_type: &AppType) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
pub fn read_live_settings(
app_type: &AppType,
) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
match app_type {
+1 -1
View File
@@ -56,7 +56,7 @@ impl McpService {
let servers = McpDao::get_all(&conn).map_err(|e| e.to_string())?;
let server = servers.iter().find(|s| s.id == id);
if let Some(server) = server {
if let Some(_server) = server {
let app = app_type.parse::<AppType>().map_err(|e| e.to_string())?;
if enabled {
// Sync server to the app
+17 -20
View File
@@ -108,14 +108,14 @@ fn sync_mcp_to_codex(
std::fs::create_dir_all(&codex_dir)?;
// Read existing config
let mut existing_content = if config_path.exists() {
let existing_content = if config_path.exists() {
std::fs::read_to_string(&config_path)?
} else {
String::new()
};
// Remove existing [mcp_servers.*] sections
let mut lines: Vec<&str> = existing_content.lines().collect();
let lines: Vec<&str> = existing_content.lines().collect();
let mut new_lines: Vec<String> = Vec::new();
let mut in_mcp_section = false;
@@ -141,14 +141,14 @@ fn sync_mcp_to_codex(
if let Some(config) = server.server_config.as_object() {
// Convert JSON config to TOML format
if let Some(command) = config.get("command").and_then(|v| v.as_str()) {
new_lines.push(format!("command = \"{}\"", command));
new_lines.push(format!("command = \"{command}\""));
}
if let Some(args) = config.get("args").and_then(|v| v.as_array()) {
let args_str: Vec<String> = args
.iter()
.filter_map(|a| a.as_str())
.map(|s| format!("\"{}\"", s))
.map(|s| format!("\"{s}\""))
.collect();
new_lines.push(format!("args = [{}]", args_str.join(", ")));
}
@@ -157,7 +157,7 @@ fn sync_mcp_to_codex(
new_lines.push("[mcp_servers.".to_string() + &server.name + ".env]");
for (key, value) in env {
if let Some(val) = value.as_str() {
new_lines.push(format!("{} = \"{}\"", key, val));
new_lines.push(format!("{key} = \"{val}\""));
}
}
}
@@ -224,9 +224,7 @@ pub fn remove_mcp_from_app(
}
}
fn remove_mcp_from_claude(
server_id: &str,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
fn remove_mcp_from_claude(server_id: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
let config_path = home.join(".claude").join("settings.json");
@@ -251,9 +249,7 @@ fn remove_mcp_from_claude(
Ok(())
}
fn remove_mcp_from_codex(
server_id: &str,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
fn remove_mcp_from_codex(server_id: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
let config_path = home.join(".codex").join("config.toml");
@@ -262,10 +258,10 @@ fn remove_mcp_from_codex(
}
let content = std::fs::read_to_string(&config_path)?;
let mut lines: Vec<&str> = content.lines().collect();
let lines: Vec<&str> = content.lines().collect();
let mut new_lines: Vec<String> = Vec::new();
let section_header = format!("[mcp_servers.{}]", server_id);
let env_header = format!("[mcp_servers.{}.env]", server_id);
let section_header = format!("[mcp_servers.{server_id}]");
let env_header = format!("[mcp_servers.{server_id}.env]");
let mut skip_section = false;
for line in &lines {
@@ -293,9 +289,7 @@ fn remove_mcp_from_codex(
Ok(())
}
fn remove_mcp_from_gemini(
server_id: &str,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
fn remove_mcp_from_gemini(server_id: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
let settings_path = home.join(".gemini").join("settings.json");
@@ -331,7 +325,8 @@ pub fn remove_mcp_from_all_apps(
}
/// Import MCP servers from Claude's settings.json
pub fn import_mcp_from_claude() -> Result<Vec<crate::models::McpServer>, Box<dyn std::error::Error + Send + Sync>> {
pub fn import_mcp_from_claude(
) -> Result<Vec<crate::models::McpServer>, Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
let config_path = home.join(".claude").join("settings.json");
@@ -365,7 +360,8 @@ pub fn import_mcp_from_claude() -> Result<Vec<crate::models::McpServer>, Box<dyn
}
/// Import MCP servers from Codex's config.toml
pub fn import_mcp_from_codex() -> Result<Vec<crate::models::McpServer>, Box<dyn std::error::Error + Send + Sync>> {
pub fn import_mcp_from_codex(
) -> Result<Vec<crate::models::McpServer>, Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
let config_path = home.join(".codex").join("config.toml");
@@ -490,7 +486,8 @@ pub fn import_mcp_from_codex() -> Result<Vec<crate::models::McpServer>, Box<dyn
}
/// Import MCP servers from Gemini's settings.json
pub fn import_mcp_from_gemini() -> Result<Vec<crate::models::McpServer>, Box<dyn std::error::Error + Send + Sync>> {
pub fn import_mcp_from_gemini(
) -> Result<Vec<crate::models::McpServer>, Box<dyn std::error::Error + Send + Sync>> {
let home = dirs::home_dir().ok_or("Cannot find home directory")?;
let settings_path = home.join(".gemini").join("settings.json");
+1 -1
View File
@@ -1,6 +1,6 @@
pub mod switch;
pub mod live_sync;
pub mod mcp_service;
pub mod mcp_sync;
pub mod prompt_service;
pub mod prompt_sync;
pub mod switch;
+14 -6
View File
@@ -14,7 +14,10 @@ impl PromptService {
}
/// Get all prompts as a HashMap (for frontend)
pub fn get_all_map(db: &DbConnection, app_type: &str) -> Result<HashMap<String, Prompt>, String> {
pub fn get_all_map(
db: &DbConnection,
app_type: &str,
) -> Result<HashMap<String, Prompt>, String> {
let conn = db.lock().map_err(|e| e.to_string())?;
PromptDao::get_all_map(&conn, app_type).map_err(|e| e.to_string())
}
@@ -48,7 +51,10 @@ impl PromptService {
// If this prompt is enabled, sync to live file
if prompt.enabled {
let app = prompt.app_type.parse::<AppType>().map_err(|e| e.to_string())?;
let app = prompt
.app_type
.parse::<AppType>()
.map_err(|e| e.to_string())?;
prompt_sync::write_live_prompt(&app, &prompt.content)?;
}
@@ -95,13 +101,15 @@ impl PromptService {
} else {
// No enabled prompt, check if we should create a backup
let prompts = PromptDao::get_all(&conn, app_type).map_err(|e| e.to_string())?;
let content_exists = prompts.iter().any(|p| p.content.trim() == live_content.trim());
let content_exists = prompts
.iter()
.any(|p| p.content.trim() == live_content.trim());
if !content_exists {
// Create a backup prompt
let timestamp = chrono::Utc::now().timestamp();
let backup = Prompt {
id: format!("backup-{}", timestamp),
id: format!("backup-{timestamp}"),
app_type: app_type.to_string(),
name: format!(
"Original Prompt {}",
@@ -157,7 +165,7 @@ impl PromptService {
}
let timestamp = chrono::Utc::now().timestamp();
let id = format!("imported-{}", timestamp);
let id = format!("imported-{timestamp}");
let prompt = Prompt {
id: id.clone(),
@@ -206,7 +214,7 @@ impl PromptService {
let timestamp = chrono::Utc::now().timestamp();
let prompt = Prompt {
id: format!("auto-imported-{}", timestamp),
id: format!("auto-imported-{timestamp}"),
app_type: app_type.to_string(),
name: format!(
"Auto-imported {}",
+8 -8
View File
@@ -36,8 +36,8 @@ pub fn read_live_prompt(app: &AppType) -> Result<Option<String>, String> {
}
fs::read_to_string(&path)
.map(|c| Some(c))
.map_err(|e| format!("Failed to read prompt file: {}", e))
.map(Some)
.map_err(|e| format!("Failed to read prompt file: {e}"))
}
/// Write content to the live prompt file (atomic write)
@@ -46,22 +46,22 @@ pub fn write_live_prompt(app: &AppType, content: &str) -> Result<(), String> {
// Ensure parent directory exists
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).map_err(|e| format!("Failed to create directory: {}", e))?;
fs::create_dir_all(parent).map_err(|e| format!("Failed to create directory: {e}"))?;
}
// Atomic write: write to temp file first, then rename
let temp_path = path.with_extension("md.tmp");
let mut file =
fs::File::create(&temp_path).map_err(|e| format!("Failed to create temp file: {}", e))?;
fs::File::create(&temp_path).map_err(|e| format!("Failed to create temp file: {e}"))?;
file.write_all(content.as_bytes())
.map_err(|e| format!("Failed to write content: {}", e))?;
.map_err(|e| format!("Failed to write content: {e}"))?;
file.sync_all()
.map_err(|e| format!("Failed to sync file: {}", e))?;
.map_err(|e| format!("Failed to sync file: {e}"))?;
fs::rename(&temp_path, &path).map_err(|e| format!("Failed to rename file: {}", e))?;
fs::rename(&temp_path, &path).map_err(|e| format!("Failed to rename file: {e}"))?;
Ok(())
}
@@ -71,7 +71,7 @@ pub fn delete_live_prompt(app: &AppType) -> Result<(), String> {
let path = get_prompt_file_path(app).ok_or("Cannot determine prompt file path")?;
if path.exists() {
fs::remove_file(&path).map_err(|e| format!("Failed to delete prompt file: {}", e))?;
fs::remove_file(&path).map_err(|e| format!("Failed to delete prompt file: {e}"))?;
}
Ok(())
+15 -10
View File
@@ -23,7 +23,8 @@ impl SwitchService {
let conn = db.lock().map_err(|e| e.to_string())?;
// Check if this is the first provider for this app type
let existing = ProviderDao::get_all(&conn, &provider.app_type).map_err(|e| e.to_string())?;
let existing =
ProviderDao::get_all(&conn, &provider.app_type).map_err(|e| e.to_string())?;
let is_first = existing.is_empty();
ProviderDao::insert(&conn, &provider).map_err(|e| e.to_string())?;
@@ -36,7 +37,7 @@ impl SwitchService {
if let Ok(app_type_enum) = provider.app_type.parse::<AppType>() {
if app_type_enum != AppType::ProxyCast {
live_sync::sync_to_live(&app_type_enum, &provider)
.map_err(|e| format!("Failed to sync: {}", e))?;
.map_err(|e| format!("Failed to sync: {e}"))?;
}
}
}
@@ -48,8 +49,12 @@ impl SwitchService {
let conn = db.lock().map_err(|e| e.to_string())?;
// Check if this is the current provider
let current = ProviderDao::get_current(&conn, &provider.app_type).map_err(|e| e.to_string())?;
let is_current = current.as_ref().map(|p| p.id == provider.id).unwrap_or(false);
let current =
ProviderDao::get_current(&conn, &provider.app_type).map_err(|e| e.to_string())?;
let is_current = current
.as_ref()
.map(|p| p.id == provider.id)
.unwrap_or(false);
ProviderDao::update(&conn, &provider).map_err(|e| e.to_string())?;
@@ -58,7 +63,7 @@ impl SwitchService {
if let Ok(app_type_enum) = provider.app_type.parse::<AppType>() {
if app_type_enum != AppType::ProxyCast {
live_sync::sync_to_live(&app_type_enum, &provider)
.map_err(|e| format!("Failed to sync: {}", e))?;
.map_err(|e| format!("Failed to sync: {e}"))?;
}
}
}
@@ -86,15 +91,15 @@ impl SwitchService {
// Get target provider
let target_provider = ProviderDao::get_by_id(&conn, app_type, id)
.map_err(|e| e.to_string())?
.ok_or_else(|| format!("Provider not found: {}", id))?;
.ok_or_else(|| format!("Provider not found: {id}"))?;
let app_type_enum = app_type.parse::<AppType>().map_err(|e| e.to_string())?;
// Skip backfill and sync for ProxyCast
if app_type_enum != AppType::ProxyCast {
// Backfill: Read current live config and save to current provider
if let Some(current_provider) = ProviderDao::get_current(&conn, app_type)
.map_err(|e| e.to_string())?
if let Some(current_provider) =
ProviderDao::get_current(&conn, app_type).map_err(|e| e.to_string())?
{
// Only backfill if switching to a different provider
if current_provider.id != id {
@@ -114,7 +119,7 @@ impl SwitchService {
// Sync target provider to live config
if app_type_enum != AppType::ProxyCast {
live_sync::sync_to_live(&app_type_enum, &target_provider)
.map_err(|e| format!("Failed to sync: {}", e))?;
.map_err(|e| format!("Failed to sync: {e}"))?;
}
Ok(())
@@ -139,7 +144,7 @@ impl SwitchService {
// Read live settings
let live_settings = live_sync::read_live_settings(&app_type_enum)
.map_err(|e| format!("Failed to read live settings: {}", e))?;
.map_err(|e| format!("Failed to read live settings: {e}"))?;
// Create default provider
let provider = Provider {