| 297 | } |
| 298 | |
| 299 | fn render_finding_card(f: &Finding) -> String { |
| 300 | let sev = match f.severity.as_str() { |
| 301 | SEV_BLOCK => "block", |
| 302 | SEV_WARN => "warn", |
| 303 | SEV_INFO => "info", |
| 304 | _ => "info", |
| 305 | }; |
| 306 | let mut card = String::new(); |
| 307 | card.push_str(&format!( |
| 308 | "<div class=\"finding {sev}\" data-severity=\"{sev}\">\n" |
| 309 | )); |
| 310 | card.push_str(&format!( |
| 311 | "<div class=\"finding-head\"><span class=\"sev-badge {sev}\">{}</span><span class=\"code\">{}</span></div>\n", |
| 312 | html_escape(sev), |
| 313 | html_escape(&f.code) |
| 314 | )); |
| 315 | card.push_str(&format!( |
| 316 | "<div class=\"message\">{}</div>\n", |
| 317 | html_escape(&f.message) |
| 318 | )); |
| 319 | card.push_str(&format!( |
| 320 | "<div class=\"focus\">focus: <code>{}</code></div>\n", |
| 321 | html_escape(&f.focus) |
| 322 | )); |
| 323 | if let Some(q) = &f.suggested_query { |
| 324 | card.push_str(&format!( |
| 325 | "<div class=\"query\">query: <code>{}</code></div>\n", |
| 326 | html_escape(q) |
| 327 | )); |
| 328 | } |
| 329 | if let Some(r) = &f.remedy { |
| 330 | card.push_str(&format!( |
| 331 | "<div class=\"remedy\">remedy: {}</div>\n", |
| 332 | html_escape(r) |
| 333 | )); |
| 334 | } |
| 335 | card.push_str("</div>\n"); |
| 336 | card |
| 337 | } |
| 338 | |
| 339 | fn render_intent(intent: &IntentReport) -> String { |
| 340 | let conform = if intent.conforms { |