Skip to main content

agentshield/output/
mod.rs

1pub mod console;
2pub mod html;
3pub mod json;
4pub mod sarif;
5
6use std::path::Path;
7
8use serde::{Deserialize, Serialize};
9
10use crate::error::Result;
11use crate::rules::policy::PolicyVerdict;
12use crate::rules::Finding;
13
14/// Output format selection.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
16#[serde(rename_all = "lowercase")]
17pub enum OutputFormat {
18    Console,
19    Json,
20    Sarif,
21    Html,
22}
23
24impl OutputFormat {
25    pub fn from_str_lenient(s: &str) -> Option<Self> {
26        match s.to_lowercase().as_str() {
27            "console" | "text" => Some(Self::Console),
28            "json" => Some(Self::Json),
29            "sarif" => Some(Self::Sarif),
30            "html" => Some(Self::Html),
31            _ => None,
32        }
33    }
34}
35
36/// Render findings into the specified format.
37///
38/// `scan_root` is used to compute stable, portable fingerprints for each
39/// finding (relative to the scan directory so they survive path changes).
40pub fn render(
41    findings: &[Finding],
42    verdict: &PolicyVerdict,
43    format: OutputFormat,
44    target_name: &str,
45    scan_root: &Path,
46) -> Result<String> {
47    match format {
48        OutputFormat::Console => Ok(console::render(findings, verdict, scan_root)),
49        OutputFormat::Json => json::render(findings, verdict, scan_root),
50        OutputFormat::Sarif => sarif::render(findings, target_name, scan_root),
51        OutputFormat::Html => html::render(findings, verdict, target_name, scan_root),
52    }
53}