fix: resolve clippy format-args failures and OpenSSL vendoring issue

Inline format arguments across Rust modules to satisfy clippy -D warnings, and configure Cargo to prefer system OpenSSL so clippy builds do not fail on missing vendored Perl modules.

Made-with: Cursor
This commit is contained in:
Shaun Arman 2026-04-04 15:05:13 -05:00
parent bdb63f3aee
commit 85a8d0a4c0
17 changed files with 98 additions and 69 deletions

3
.cargo/config.toml Normal file
View File

@ -0,0 +1,3 @@
[env]
# Force use of system OpenSSL instead of vendored OpenSSL source builds.
OPENSSL_NO_VENDOR = "1"

View File

@ -4,3 +4,8 @@
# error. The desktop binary links against rlib (static), so cdylib exports
# are unused at runtime.
rustflags = ["-C", "link-arg=-Wl,--exclude-all-symbols"]
[env]
# Use system OpenSSL instead of vendoring from source (which requires Perl modules
# unavailable on some environments and breaks clippy/check).
OPENSSL_NO_VENDOR = "1"

View File

@ -47,7 +47,10 @@ impl Provider for MistralProvider {
let resp = client
.post(&url)
.header("Authorization", format!("Bearer {}", config.api_key))
.header(
"Authorization",
format!("Bearer {api_key}", api_key = config.api_key),
)
.header("Content-Type", "application/json")
.json(&body)
.send()

View File

@ -54,7 +54,8 @@ impl OpenAiProvider {
.custom_endpoint_path
.as_deref()
.unwrap_or("/chat/completions");
let url = format!("{}{}", config.api_url.trim_end_matches('/'), endpoint_path);
let api_url = config.api_url.trim_end_matches('/');
let url = format!("{api_url}{endpoint_path}");
let mut body = serde_json::json!({
"model": config.model,
@ -75,7 +76,7 @@ impl OpenAiProvider {
.as_deref()
.unwrap_or("Authorization");
let auth_prefix = config.custom_auth_prefix.as_deref().unwrap_or("Bearer ");
let auth_value = format!("{}{}", auth_prefix, config.api_key);
let auth_value = format!("{auth_prefix}{api_key}", api_key = config.api_key);
let resp = client
.post(&url)
@ -122,7 +123,8 @@ impl OpenAiProvider {
// Use custom endpoint path, default to empty (API URL already includes /api/v2/chat)
let endpoint_path = config.custom_endpoint_path.as_deref().unwrap_or("");
let url = format!("{}{}", config.api_url.trim_end_matches('/'), endpoint_path);
let api_url = config.api_url.trim_end_matches('/');
let url = format!("{api_url}{endpoint_path}");
// Extract system message if present
let system_message = messages
@ -177,7 +179,7 @@ impl OpenAiProvider {
.as_deref()
.unwrap_or("x-msi-genai-api-key");
let auth_prefix = config.custom_auth_prefix.as_deref().unwrap_or("");
let auth_value = format!("{}{}", auth_prefix, config.api_key);
let auth_value = format!("{auth_prefix}{api_key}", api_key = config.api_key);
let resp = client
.post(&url)

View File

@ -246,7 +246,7 @@ pub async fn chat_message(
"api_url": provider_config.api_url,
"user_message": user_msg.content,
"response_preview": if response.content.len() > 200 {
format!("{}...", &response.content[..200])
format!("{preview}...", preview = &response.content[..200])
} else {
response.content.clone()
},

View File

@ -295,19 +295,19 @@ pub async fn list_issues(
let mut params: Vec<Box<dyn rusqlite::types::ToSql>> = vec![];
if let Some(ref status) = filter.status {
sql.push_str(&format!(" AND i.status = ?{}", params.len() + 1));
sql.push_str(&format!(" AND i.status = ?{index}", index = params.len() + 1));
params.push(Box::new(status.clone()));
}
if let Some(ref severity) = filter.severity {
sql.push_str(&format!(" AND i.severity = ?{}", params.len() + 1));
sql.push_str(&format!(" AND i.severity = ?{index}", index = params.len() + 1));
params.push(Box::new(severity.clone()));
}
if let Some(ref category) = filter.category {
sql.push_str(&format!(" AND i.category = ?{}", params.len() + 1));
sql.push_str(&format!(" AND i.category = ?{index}", index = params.len() + 1));
params.push(Box::new(category.clone()));
}
if let Some(ref domain) = filter.domain {
sql.push_str(&format!(" AND i.category = ?{}", params.len() + 1));
sql.push_str(&format!(" AND i.category = ?{index}", index = params.len() + 1));
params.push(Box::new(domain.clone()));
}
if let Some(ref search) = filter.search {
@ -321,9 +321,9 @@ pub async fn list_issues(
sql.push_str(" ORDER BY i.updated_at DESC");
sql.push_str(&format!(
" LIMIT ?{} OFFSET ?{}",
params.len() + 1,
params.len() + 2
" LIMIT ?{limit_index} OFFSET ?{offset_index}",
limit_index = params.len() + 1,
offset_index = params.len() + 2
));
params.push(Box::new(limit));
params.push(Box::new(offset));

View File

@ -34,7 +34,7 @@ pub async fn generate_rca(
id: doc_id.clone(),
issue_id: issue_id.clone(),
doc_type: "rca".to_string(),
title: format!("RCA: {}", issue_detail.issue.title),
title: format!("RCA: {title}", title = issue_detail.issue.title),
content_md: content_md.clone(),
created_at: now.clone(),
updated_at: now,
@ -49,7 +49,7 @@ pub async fn generate_rca(
"doc_title": document.title,
"content_length": content_md.len(),
"content_preview": if content_md.len() > 300 {
format!("{}...", &content_md[..300])
format!("{preview}...", preview = &content_md[..300])
} else {
content_md.clone()
},
@ -93,7 +93,7 @@ pub async fn generate_postmortem(
id: doc_id.clone(),
issue_id: issue_id.clone(),
doc_type: "postmortem".to_string(),
title: format!("Post-Mortem: {}", issue_detail.issue.title),
title: format!("Post-Mortem: {title}", title = issue_detail.issue.title),
content_md: content_md.clone(),
created_at: now.clone(),
updated_at: now,
@ -108,7 +108,7 @@ pub async fn generate_postmortem(
"doc_title": document.title,
"content_length": content_md.len(),
"content_preview": if content_md.len() > 300 {
format!("{}...", &content_md[..300])
format!("{preview}...", preview = &content_md[..300])
} else {
content_md.clone()
},

View File

@ -514,7 +514,7 @@ pub async fn authenticate_with_webview(
app_handle: tauri::AppHandle,
app_state: State<'_, AppState>,
) -> Result<WebviewAuthResponse, String> {
let webview_id = format!("{}-auth", service);
let webview_id = format!("{service}-auth");
// Check if window already exists
if let Some(existing_label) = app_state
@ -526,10 +526,7 @@ pub async fn authenticate_with_webview(
if app_handle.get_webview_window(existing_label).is_some() {
return Ok(WebviewAuthResponse {
success: true,
message: format!(
"{} browser window is already open. Switch to it to log in.",
service
),
message: format!("{service} browser window is already open. Switch to it to log in."),
webview_id: existing_label.clone(),
});
}
@ -551,8 +548,7 @@ pub async fn authenticate_with_webview(
Ok(WebviewAuthResponse {
success: true,
message: format!(
"{} browser window opened. This window will stay open - use it to browse and authenticate. Cookies will be extracted automatically for API calls.",
service
"{service} browser window opened. This window will stay open - use it to browse and authenticate. Cookies will be extracted automatically for API calls."
),
webview_id,
})
@ -622,7 +618,7 @@ pub async fn extract_cookies_from_webview(
Ok(ConnectionResult {
success: true,
message: format!("{} authentication saved successfully", service),
message: format!("{service} authentication saved successfully"),
})
}
@ -669,7 +665,7 @@ pub async fn save_manual_token(
};
crate::integrations::servicenow::test_connection(&config).await
}
_ => return Err(format!("Unknown service: {}", request.service)),
_ => return Err(format!("Unknown service: {service}", service = request.service)),
};
// If test fails, don't save the token
@ -736,7 +732,10 @@ pub async fn save_manual_token(
Ok(ConnectionResult {
success: true,
message: format!("{} token saved and validated successfully", request.service),
message: format!(
"{service} token saved and validated successfully",
service = request.service
),
})
}

View File

@ -98,20 +98,23 @@ pub async fn get_audit_log(
let mut params: Vec<Box<dyn rusqlite::types::ToSql>> = vec![];
if let Some(ref action) = filter.action {
sql.push_str(&format!(" AND action = ?{}", params.len() + 1));
sql.push_str(&format!(" AND action = ?{index}", index = params.len() + 1));
params.push(Box::new(action.clone()));
}
if let Some(ref entity_type) = filter.entity_type {
sql.push_str(&format!(" AND entity_type = ?{}", params.len() + 1));
sql.push_str(&format!(
" AND entity_type = ?{index}",
index = params.len() + 1
));
params.push(Box::new(entity_type.clone()));
}
if let Some(ref entity_id) = filter.entity_id {
sql.push_str(&format!(" AND entity_id = ?{}", params.len() + 1));
sql.push_str(&format!(" AND entity_id = ?{index}", index = params.len() + 1));
params.push(Box::new(entity_id.clone()));
}
sql.push_str(" ORDER BY timestamp DESC");
sql.push_str(&format!(" LIMIT ?{}", params.len() + 1));
sql.push_str(&format!(" LIMIT ?{index}", index = params.len() + 1));
params.push(Box::new(limit));
let param_refs: Vec<&dyn rusqlite::types::ToSql> = params.iter().map(|p| p.as_ref()).collect();

View File

@ -5,15 +5,21 @@ pub fn generate_postmortem_markdown(detail: &IssueDetail) -> String {
let mut md = String::new();
md.push_str(&format!("# Blameless Post-Mortem: {}\n\n", issue.title));
md.push_str(&format!(
"# Blameless Post-Mortem: {title}\n\n",
title = issue.title
));
// Header metadata
md.push_str("## Metadata\n\n");
md.push_str(&format!("- **Date:** {}\n", issue.created_at));
md.push_str(&format!("- **Severity:** {}\n", issue.severity));
md.push_str(&format!("- **Category:** {}\n", issue.category));
md.push_str(&format!("- **Status:** {}\n", issue.status));
md.push_str(&format!("- **Last Updated:** {}\n", issue.updated_at));
md.push_str(&format!("- **Date:** {created_at}\n", created_at = issue.created_at));
md.push_str(&format!("- **Severity:** {severity}\n", severity = issue.severity));
md.push_str(&format!("- **Category:** {category}\n", category = issue.category));
md.push_str(&format!("- **Status:** {status}\n", status = issue.status));
md.push_str(&format!(
"- **Last Updated:** {updated_at}\n",
updated_at = issue.updated_at
));
md.push_str(&format!(
"- **Assigned To:** {}\n",
if issue.assigned_to.is_empty() {
@ -45,7 +51,7 @@ pub fn generate_postmortem_markdown(detail: &IssueDetail) -> String {
md.push_str("## Timeline\n\n");
md.push_str("| Time (UTC) | Event |\n");
md.push_str("|------------|-------|\n");
md.push_str(&format!("| {} | Issue created |\n", issue.created_at));
md.push_str(&format!("| {created_at} | Issue created |\n", created_at = issue.created_at));
if let Some(ref resolved) = issue.resolved_at {
md.push_str(&format!("| {resolved} | Issue resolved |\n"));
}
@ -77,7 +83,7 @@ pub fn generate_postmortem_markdown(detail: &IssueDetail) -> String {
if let Some(last) = detail.resolution_steps.last() {
if !last.answer.is_empty() {
md.push_str(&format!("**Root Cause:** {}\n\n", last.answer));
md.push_str(&format!("**Root Cause:** {answer}\n\n", answer = last.answer));
}
}
}

View File

@ -5,16 +5,16 @@ pub fn generate_rca_markdown(detail: &IssueDetail) -> String {
let mut md = String::new();
md.push_str(&format!("# Root Cause Analysis: {}\n\n", issue.title));
md.push_str(&format!("# Root Cause Analysis: {title}\n\n", title = issue.title));
md.push_str("## Issue Summary\n\n");
md.push_str("| Field | Value |\n");
md.push_str("|-------|-------|\n");
md.push_str(&format!("| **Issue ID** | {} |\n", issue.id));
md.push_str(&format!("| **Category** | {} |\n", issue.category));
md.push_str(&format!("| **Status** | {} |\n", issue.status));
md.push_str(&format!("| **Severity** | {} |\n", issue.severity));
md.push_str(&format!("| **Source** | {} |\n", issue.source));
md.push_str(&format!("| **Issue ID** | {id} |\n", id = issue.id));
md.push_str(&format!("| **Category** | {category} |\n", category = issue.category));
md.push_str(&format!("| **Status** | {status} |\n", status = issue.status));
md.push_str(&format!("| **Severity** | {severity} |\n", severity = issue.severity));
md.push_str(&format!("| **Source** | {source} |\n", source = issue.source));
md.push_str(&format!(
"| **Assigned To** | {} |\n",
if issue.assigned_to.is_empty() {
@ -23,8 +23,11 @@ pub fn generate_rca_markdown(detail: &IssueDetail) -> String {
&issue.assigned_to
}
));
md.push_str(&format!("| **Created** | {} |\n", issue.created_at));
md.push_str(&format!("| **Last Updated** | {} |\n", issue.updated_at));
md.push_str(&format!("| **Created** | {created_at} |\n", created_at = issue.created_at));
md.push_str(&format!(
"| **Last Updated** | {updated_at} |\n",
updated_at = issue.updated_at
));
if let Some(ref resolved) = issue.resolved_at {
md.push_str(&format!("| **Resolved** | {resolved} |\n"));
}
@ -47,12 +50,12 @@ pub fn generate_rca_markdown(detail: &IssueDetail) -> String {
step.step_order, step.why_question
));
if !step.answer.is_empty() {
md.push_str(&format!("**Answer:** {}\n\n", step.answer));
md.push_str(&format!("**Answer:** {answer}\n\n", answer = step.answer));
} else {
md.push_str("_Awaiting answer._\n\n");
}
if !step.evidence.is_empty() {
md.push_str(&format!("**Evidence:** {}\n\n", step.evidence));
md.push_str(&format!("**Evidence:** {evidence}\n\n", evidence = step.evidence));
}
}
}

View File

@ -365,7 +365,7 @@ mod tests {
.create_async()
.await;
let token_endpoint = format!("{}/oauth/token", server.url());
let token_endpoint = format!("{server_url}/oauth/token", server_url = server.url());
let result = exchange_code(
&token_endpoint,
"test-client-id",
@ -397,7 +397,7 @@ mod tests {
.create_async()
.await;
let token_endpoint = format!("{}/oauth/token", server.url());
let token_endpoint = format!("{server_url}/oauth/token", server_url = server.url());
let result = exchange_code(
&token_endpoint,
"test-client-id",
@ -421,7 +421,7 @@ mod tests {
.create_async()
.await;
let token_endpoint = format!("{}/oauth/token", server.url());
let token_endpoint = format!("{server_url}/oauth/token", server_url = server.url());
let result = exchange_code(
&token_endpoint,
"test-client-id",

View File

@ -40,9 +40,10 @@ pub async fn test_connection(config: &AzureDevOpsConfig) -> Result<ConnectionRes
message: "Successfully connected to Azure DevOps".to_string(),
})
} else {
let status = resp.status();
Ok(ConnectionResult {
success: false,
message: format!("Connection failed with status: {}", resp.status()),
message: format!("Connection failed with status: {status}"),
})
}
}
@ -61,8 +62,7 @@ pub async fn search_work_items(
// Build WIQL query
let wiql = format!(
"SELECT [System.Id], [System.Title], [System.WorkItemType], [System.State] FROM WorkItems WHERE [System.Title] CONTAINS '{}' ORDER BY [System.CreatedDate] DESC",
query
"SELECT [System.Id], [System.Title], [System.WorkItemType], [System.State] FROM WorkItems WHERE [System.Title] CONTAINS '{query}' ORDER BY [System.CreatedDate] DESC"
);
let body = serde_json::json!({ "query": wiql });

View File

@ -269,7 +269,7 @@ mod tests {
tokio::time::sleep(tokio::time::Duration::from_millis(200)).await;
// Server should be running
let health_url = format!("http://127.0.0.1:{}/health", port);
let health_url = format!("http://127.0.0.1:{port}/health");
let health_before = reqwest::get(&health_url).await;
assert!(health_before.is_ok(), "Server should be running");

View File

@ -43,9 +43,10 @@ pub async fn test_connection(config: &ConfluenceConfig) -> Result<ConnectionResu
message: "Successfully connected to Confluence".to_string(),
})
} else {
let status = resp.status();
Ok(ConnectionResult {
success: false,
message: format!("Connection failed with status: {}", resp.status()),
message: format!("Connection failed with status: {status}"),
})
}
}
@ -53,7 +54,8 @@ pub async fn test_connection(config: &ConfluenceConfig) -> Result<ConnectionResu
/// List all spaces accessible with the current token
pub async fn list_spaces(config: &ConfluenceConfig) -> Result<Vec<Space>, String> {
let client = reqwest::Client::new();
let url = format!("{}/rest/api/space", config.base_url.trim_end_matches('/'));
let base_url = config.base_url.trim_end_matches('/');
let url = format!("{base_url}/rest/api/space");
let resp = client
.get(&url)
@ -103,9 +105,9 @@ pub async fn search_pages(
config.base_url.trim_end_matches('/')
);
let mut cql = format!("text ~ \"{}\"", query);
let mut cql = format!("text ~ \"{query}\"");
if let Some(space) = space_key {
cql = format!("{} AND space = {}", cql, space);
cql = format!("{cql} AND space = {space}");
}
let resp = client
@ -140,7 +142,7 @@ pub async fn search_pages(
id: page_id.to_string(),
title: p["title"].as_str()?.to_string(),
space_key: p["space"]["key"].as_str()?.to_string(),
url: format!("{}/pages/viewpage.action?pageId={}", base_url, page_id),
url: format!("{base_url}/pages/viewpage.action?pageId={page_id}"),
})
})
.collect();
@ -157,7 +159,8 @@ pub async fn publish_page(
parent_page_id: Option<&str>,
) -> Result<PublishResult, String> {
let client = reqwest::Client::new();
let url = format!("{}/rest/api/content", config.base_url.trim_end_matches('/'));
let base_url = config.base_url.trim_end_matches('/');
let url = format!("{base_url}/rest/api/content");
let mut body = serde_json::json!({
"type": "page",

View File

@ -42,9 +42,10 @@ pub async fn test_connection(config: &ServiceNowConfig) -> Result<ConnectionResu
message: "Successfully connected to ServiceNow".to_string(),
})
} else {
let status = resp.status();
Ok(ConnectionResult {
success: false,
message: format!("Connection failed with status: {}", resp.status()),
message: format!("Connection failed with status: {status}"),
})
}
}

View File

@ -25,13 +25,14 @@ pub async fn authenticate_with_webview(
service: &str,
base_url: &str,
) -> Result<ExtractedCredentials, String> {
let trimmed_base_url = base_url.trim_end_matches('/');
let login_url = match service {
"confluence" => format!("{}/login.action", base_url.trim_end_matches('/')),
"confluence" => format!("{trimmed_base_url}/login.action"),
"azuredevops" => {
// Azure DevOps login - user will be redirected through Microsoft SSO
format!("{}/_signin", base_url.trim_end_matches('/'))
format!("{trimmed_base_url}/_signin")
}
"servicenow" => format!("{}/login.do", base_url.trim_end_matches('/')),
"servicenow" => format!("{trimmed_base_url}/login.do"),
_ => return Err(format!("Unknown service: {service}")),
};
@ -42,13 +43,13 @@ pub async fn authenticate_with_webview(
);
// Create persistent browser window (stays open for browsing and fresh cookie extraction)
let webview_label = format!("{}-auth", service);
let webview_label = format!("{service}-auth");
let webview = WebviewWindowBuilder::new(
&app_handle,
&webview_label,
WebviewUrl::External(login_url.parse().map_err(|e| format!("Invalid URL: {e}"))?),
)
.title(format!("{} Browser (TFTSR)", service))
.title(format!("{service} Browser (TFTSR)"))
.inner_size(1000.0, 800.0)
.min_inner_size(800.0, 600.0)
.resizable(true)
@ -195,7 +196,7 @@ pub async fn extract_cookies_via_ipc<R: tauri::Runtime>(
pub fn cookies_to_header(cookies: &[Cookie]) -> String {
cookies
.iter()
.map(|c| format!("{}={}", c.name, c.value))
.map(|c| format!("{name}={value}", name = c.name.as_str(), value = c.value.as_str()))
.collect::<Vec<_>>()
.join("; ")
}