style: apply cargo fmt formatting

This commit is contained in:
Shaun Arman 2026-03-15 12:43:46 -05:00
parent 1011fc1db4
commit c8a717adee
16 changed files with 159 additions and 96 deletions

View File

@ -106,10 +106,7 @@ impl Provider for AnthropicProvider {
})
});
let model = json["model"]
.as_str()
.unwrap_or(&config.model)
.to_string();
let model = json["model"].as_str().unwrap_or(&config.model).to_string();
Ok(ChatResponse {
content,

View File

@ -30,10 +30,7 @@ impl Provider for OpenAiProvider {
config: &ProviderConfig,
) -> anyhow::Result<ChatResponse> {
let client = reqwest::Client::new();
let url = format!(
"{}/chat/completions",
config.api_url.trim_end_matches('/')
);
let url = format!("{}/chat/completions", config.api_url.trim_end_matches('/'));
let body = serde_json::json!({
"model": config.model,

View File

@ -54,7 +54,13 @@ mod tests {
#[test]
fn test_write_audit_event_inserts_row() {
let conn = setup_test_db();
write_audit_event(&conn, "test_action", "issue", "issue-123", r#"{"key":"val"}"#)
write_audit_event(
&conn,
"test_action",
"issue",
"issue-123",
r#"{"key":"val"}"#,
)
.expect("should insert");
let count: i64 = conn

View File

@ -48,10 +48,7 @@ pub async fn analyze_logs(
},
Message {
role: "user".into(),
content: format!(
"Analyze logs for issue {}:\n\n{}",
issue_id, log_contents
),
content: format!("Analyze logs for issue {}:\n\n{}", issue_id, log_contents),
},
];
@ -61,8 +58,13 @@ pub async fn analyze_logs(
.map_err(|e| e.to_string())?;
let content = &response.content;
let summary = extract_section(content, "SUMMARY:")
.unwrap_or_else(|| content.lines().next().unwrap_or("Analysis complete").to_string());
let summary = extract_section(content, "SUMMARY:").unwrap_or_else(|| {
content
.lines()
.next()
.unwrap_or("Analysis complete")
.to_string()
});
let key_findings = extract_list(content, "KEY_FINDINGS:");
let suggested_why1 = extract_section(content, "FIRST_WHY:")
.unwrap_or_else(|| "Why did this issue occur?".to_string());
@ -76,7 +78,8 @@ pub async fn analyze_logs(
"ai_analyze_logs".to_string(),
"issue".to_string(),
issue_id.clone(),
serde_json::json!({ "log_file_ids": log_file_ids, "provider": provider_config.name }).to_string(),
serde_json::json!({ "log_file_ids": log_file_ids, "provider": provider_config.name })
.to_string(),
);
db.execute(
"INSERT INTO audit_log (id, timestamp, action, entity_type, entity_id, user_id, details) \
@ -275,10 +278,7 @@ pub async fn list_providers() -> Result<Vec<ProviderInfo>, String> {
ProviderInfo {
name: "gemini".to_string(),
supports_streaming: false,
models: vec![
"gemini-1.5-pro".to_string(),
"gemini-1.5-flash".to_string(),
],
models: vec!["gemini-1.5-pro".to_string(), "gemini-1.5-flash".to_string()],
},
ProviderInfo {
name: "mistral".to_string(),

View File

@ -64,8 +64,13 @@ pub async fn upload_log_file(
"INSERT INTO audit_log (id, timestamp, action, entity_type, entity_id, user_id, details) \
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
rusqlite::params![
entry.id, entry.timestamp, entry.action,
entry.entity_type, entry.entity_id, entry.user_id, entry.details
entry.id,
entry.timestamp,
entry.action,
entry.entity_type,
entry.entity_id,
entry.user_id,
entry.details
],
);
@ -163,14 +168,16 @@ pub async fn apply_redactions(
.unwrap_or_default();
drop(db);
raw.into_iter()
.map(|(id, pii_type, start, end, original, replacement)| pii::PiiSpan {
.map(
|(id, pii_type, start, end, original, replacement)| pii::PiiSpan {
id,
pii_type,
start: start as usize,
end: end as usize,
original,
replacement,
})
},
)
.filter(|span| approved_span_ids.contains(&span.id))
.collect()
};

View File

@ -247,22 +247,28 @@ pub async fn update_issue(
}
#[tauri::command]
pub async fn delete_issue(
issue_id: String,
state: State<'_, AppState>,
) -> Result<(), String> {
pub async fn delete_issue(issue_id: String, state: State<'_, AppState>) -> Result<(), String> {
let db = state.db.lock().map_err(|e| e.to_string())?;
// Delete related records (CASCADE should handle this, but be explicit)
db.execute("DELETE FROM ai_messages WHERE conversation_id IN (SELECT id FROM ai_conversations WHERE issue_id = ?1)", [&issue_id])
.map_err(|e| e.to_string())?;
db.execute("DELETE FROM ai_conversations WHERE issue_id = ?1", [&issue_id])
db.execute(
"DELETE FROM ai_conversations WHERE issue_id = ?1",
[&issue_id],
)
.map_err(|e| e.to_string())?;
db.execute("DELETE FROM pii_spans WHERE log_file_id IN (SELECT id FROM log_files WHERE issue_id = ?1)", [&issue_id])
db.execute(
"DELETE FROM pii_spans WHERE log_file_id IN (SELECT id FROM log_files WHERE issue_id = ?1)",
[&issue_id],
)
.map_err(|e| e.to_string())?;
db.execute("DELETE FROM log_files WHERE issue_id = ?1", [&issue_id])
.map_err(|e| e.to_string())?;
db.execute("DELETE FROM resolution_steps WHERE issue_id = ?1", [&issue_id])
db.execute(
"DELETE FROM resolution_steps WHERE issue_id = ?1",
[&issue_id],
)
.map_err(|e| e.to_string())?;
db.execute("DELETE FROM issues WHERE id = ?1", [&issue_id])
.map_err(|e| e.to_string())?;
@ -364,13 +370,7 @@ pub async fn add_five_why(
evidence: String,
state: State<'_, AppState>,
) -> Result<ResolutionStep, String> {
let step = ResolutionStep::new(
issue_id.clone(),
step_order,
why_question,
answer,
evidence,
);
let step = ResolutionStep::new(issue_id.clone(), step_order, why_question, answer, evidence);
let db = state.db.lock().map_err(|e| e.to_string())?;
db.execute(
@ -444,8 +444,13 @@ pub async fn add_timeline_event(
"INSERT INTO audit_log (id, timestamp, action, entity_type, entity_id, user_id, details) \
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
rusqlite::params![
entry.id, entry.timestamp, entry.action,
entry.entity_type, entry.entity_id, entry.user_id, entry.details
entry.id,
entry.timestamp,
entry.action,
entry.entity_type,
entry.entity_id,
entry.user_id,
entry.details
],
)
.map_err(|e| e.to_string())?;

View File

@ -52,8 +52,13 @@ pub async fn generate_rca(
"INSERT INTO audit_log (id, timestamp, action, entity_type, entity_id, user_id, details) \
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
rusqlite::params![
entry.id, entry.timestamp, entry.action,
entry.entity_type, entry.entity_id, entry.user_id, entry.details
entry.id,
entry.timestamp,
entry.action,
entry.entity_type,
entry.entity_id,
entry.user_id,
entry.details
],
);
@ -94,8 +99,13 @@ pub async fn generate_postmortem(
"INSERT INTO audit_log (id, timestamp, action, entity_type, entity_id, user_id, details) \
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
rusqlite::params![
entry.id, entry.timestamp, entry.action,
entry.entity_type, entry.entity_id, entry.user_id, entry.details
entry.id,
entry.timestamp,
entry.action,
entry.entity_type,
entry.entity_id,
entry.user_id,
entry.details
],
);
@ -103,10 +113,7 @@ pub async fn generate_postmortem(
}
#[tauri::command]
pub async fn update_document(
doc_id: String,
content_md: String,
) -> Result<(), String> {
pub async fn update_document(doc_id: String, content_md: String) -> Result<(), String> {
// Documents are generated on-demand and held in memory / frontend state.
// This is a no-op placeholder. In a future version with a documents table,
// this would persist updates.

View File

@ -9,9 +9,7 @@ use crate::state::{AppSettings, AppState};
#[tauri::command]
pub async fn check_ollama_installed() -> Result<OllamaStatus, String> {
installer::check_ollama()
.await
.map_err(|e| e.to_string())
installer::check_ollama().await.map_err(|e| e.to_string())
}
#[tauri::command]
@ -55,9 +53,7 @@ pub async fn recommend_models() -> Result<Vec<ModelRecommendation>, String> {
// --- Settings commands ---
#[tauri::command]
pub async fn get_settings(
state: tauri::State<'_, AppState>,
) -> Result<AppSettings, String> {
pub async fn get_settings(state: tauri::State<'_, AppState>) -> Result<AppSettings, String> {
state
.settings
.lock()

View File

@ -35,8 +35,7 @@ pub fn export_pdf(content_md: &str, title: &str, output_path: &str) -> anyhow::R
for line_info in &lines {
if line_count >= max_lines_per_page {
let (new_page, new_layer) =
doc.add_page(Mm(210.0), Mm(297.0), "Layer 1");
let (new_page, new_layer) = doc.add_page(Mm(210.0), Mm(297.0), "Layer 1");
current_layer = doc.get_page(new_page).get_layer(new_layer);
y_pos = margin_top;
line_count = 0;
@ -185,13 +184,18 @@ mod tests {
#[test]
fn test_markdown_to_lines_title() {
let lines = markdown_to_lines("# My Title\n\nSome text");
assert!(lines.iter().any(|l| l.text == "My Title" && matches!(l.style, LineStyle::Title)));
assert!(lines
.iter()
.any(|l| l.text == "My Title" && matches!(l.style, LineStyle::Title)));
}
#[test]
fn test_markdown_to_lines_heading() {
let lines = markdown_to_lines("## Section\n### Subsection");
let headings: Vec<_> = lines.iter().filter(|l| matches!(l.style, LineStyle::Heading)).collect();
let headings: Vec<_> = lines
.iter()
.filter(|l| matches!(l.style, LineStyle::Heading))
.collect();
assert_eq!(headings.len(), 2);
}
@ -204,7 +208,9 @@ mod tests {
#[test]
fn test_markdown_to_lines_table_row() {
let lines = markdown_to_lines("| Col1 | Col2 |\n|------|------|\n| A | B |");
assert!(lines.iter().any(|l| l.text.contains("Col1") && l.text.contains("Col2")));
assert!(lines
.iter()
.any(|l| l.text.contains("Col1") && l.text.contains("Col2")));
}
#[test]

View File

@ -5,10 +5,7 @@ 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: {}\n\n", issue.title));
// Header metadata
md.push_str("## Metadata\n\n");
@ -19,7 +16,11 @@ pub fn generate_postmortem_markdown(detail: &IssueDetail) -> String {
md.push_str(&format!("- **Last Updated:** {}\n", issue.updated_at));
md.push_str(&format!(
"- **Assigned To:** {}\n",
if issue.assigned_to.is_empty() { "_Unassigned_" } else { &issue.assigned_to }
if issue.assigned_to.is_empty() {
"_Unassigned_"
} else {
&issue.assigned_to
}
));
md.push_str("- **Authors:** _[Add authors]_\n");
md.push_str("- **Reviewers:** _[Add reviewers]_\n\n");

View File

@ -15,7 +15,14 @@ pub fn generate_rca_markdown(detail: &IssueDetail) -> String {
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!("| **Assigned To** | {} |\n", if issue.assigned_to.is_empty() { "Unassigned" } else { &issue.assigned_to }));
md.push_str(&format!(
"| **Assigned To** | {} |\n",
if issue.assigned_to.is_empty() {
"Unassigned"
} else {
&issue.assigned_to
}
));
md.push_str(&format!("| **Created** | {} |\n", issue.created_at));
md.push_str(&format!("| **Last Updated** | {} |\n", issue.updated_at));
if let Some(ref resolved) = issue.resolved_at {

View File

@ -19,7 +19,10 @@ pub struct WorkItem {
}
pub async fn test_connection(_config: &AzureDevOpsConfig) -> Result<ConnectionResult, String> {
Err("Azure DevOps integration available in v0.2. Please update to the latest version.".to_string())
Err(
"Azure DevOps integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn create_work_item(
@ -29,14 +32,20 @@ pub async fn create_work_item(
_work_item_type: &str,
_severity: &str,
) -> Result<TicketResult, String> {
Err("Azure DevOps integration available in v0.2. Please update to the latest version.".to_string())
Err(
"Azure DevOps integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn get_work_item(
_config: &AzureDevOpsConfig,
_work_item_id: i64,
) -> Result<WorkItem, String> {
Err("Azure DevOps integration available in v0.2. Please update to the latest version.".to_string())
Err(
"Azure DevOps integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn update_work_item(
@ -44,5 +53,8 @@ pub async fn update_work_item(
_work_item_id: i64,
_updates: serde_json::Value,
) -> Result<TicketResult, String> {
Err("Azure DevOps integration available in v0.2. Please update to the latest version.".to_string())
Err(
"Azure DevOps integration available in v0.2. Please update to the latest version."
.to_string(),
)
}

View File

@ -24,11 +24,17 @@ pub struct Page {
}
pub async fn test_connection(_config: &ConfluenceConfig) -> Result<ConnectionResult, String> {
Err("Confluence integration available in v0.2. Please update to the latest version.".to_string())
Err(
"Confluence integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn list_spaces(_config: &ConfluenceConfig) -> Result<Vec<Space>, String> {
Err("Confluence integration available in v0.2. Please update to the latest version.".to_string())
Err(
"Confluence integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn publish_page(
@ -38,7 +44,10 @@ pub async fn publish_page(
_content_html: &str,
_parent_page_id: Option<&str>,
) -> Result<PublishResult, String> {
Err("Confluence integration available in v0.2. Please update to the latest version.".to_string())
Err(
"Confluence integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn update_page(
@ -48,5 +57,8 @@ pub async fn update_page(
_content_html: &str,
_version: i32,
) -> Result<PublishResult, String> {
Err("Confluence integration available in v0.2. Please update to the latest version.".to_string())
Err(
"Confluence integration available in v0.2. Please update to the latest version."
.to_string(),
)
}

View File

@ -20,7 +20,10 @@ pub struct Incident {
}
pub async fn test_connection(_config: &ServiceNowConfig) -> Result<ConnectionResult, String> {
Err("ServiceNow integration available in v0.2. Please update to the latest version.".to_string())
Err(
"ServiceNow integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn create_incident(
@ -30,14 +33,20 @@ pub async fn create_incident(
_urgency: &str,
_impact: &str,
) -> Result<TicketResult, String> {
Err("ServiceNow integration available in v0.2. Please update to the latest version.".to_string())
Err(
"ServiceNow integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn get_incident(
_config: &ServiceNowConfig,
_incident_number: &str,
) -> Result<Incident, String> {
Err("ServiceNow integration available in v0.2. Please update to the latest version.".to_string())
Err(
"ServiceNow integration available in v0.2. Please update to the latest version."
.to_string(),
)
}
pub async fn update_incident(
@ -45,5 +54,8 @@ pub async fn update_incident(
_incident_number: &str,
_updates: serde_json::Value,
) -> Result<TicketResult, String> {
Err("ServiceNow integration available in v0.2. Please update to the latest version.".to_string())
Err(
"ServiceNow integration available in v0.2. Please update to the latest version."
.to_string(),
)
}

View File

@ -8,13 +8,9 @@ pub async fn check_ollama() -> anyhow::Result<OllamaStatus> {
"which"
};
let which_result = std::process::Command::new(which_cmd)
.arg("ollama")
.output();
let which_result = std::process::Command::new(which_cmd).arg("ollama").output();
let installed = which_result
.map(|o| o.status.success())
.unwrap_or(false);
let installed = which_result.map(|o| o.status.success()).unwrap_or(false);
let version = if installed {
std::process::Command::new("ollama")
@ -104,7 +100,10 @@ mod tests {
fn test_macos_install_guide() {
let guide = get_install_instructions("macos");
assert_eq!(guide.platform, "macOS");
assert!(guide.steps.iter().any(|s| s.contains("dmg") || s.contains("Applications")));
assert!(guide
.steps
.iter()
.any(|s| s.contains("dmg") || s.contains("Applications")));
}
#[test]

View File

@ -46,8 +46,7 @@ pub fn recommend_models(hw: &HardwareInfo) -> Vec<ModelRecommendation> {
size: "40 GB".to_string(),
min_ram_gb: 48.0,
description: "Full Llama 3.1 70B. Best quality, requires significant RAM.".to_string(),
recommended: ram >= 48.0
|| (has_gpu && hw.gpu_vram_gb.unwrap_or(0.0) >= 40.0),
recommended: ram >= 48.0 || (has_gpu && hw.gpu_vram_gb.unwrap_or(0.0) >= 40.0),
},
];