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::Finding;
12use crate::rules::policy::PolicyVerdict;
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    render_with_metadata(findings, verdict, format, target_name, scan_root, &[])
48}
49
50/// Render findings with registry metadata for enriched formats such as SARIF.
51pub fn render_with_metadata(
52    findings: &[Finding],
53    verdict: &PolicyVerdict,
54    format: OutputFormat,
55    target_name: &str,
56    scan_root: &Path,
57    rule_metadata: &[crate::rules::RuleMetadata],
58) -> Result<String> {
59    match format {
60        OutputFormat::Console => Ok(console::render(findings, verdict, scan_root)),
61        OutputFormat::Json => json::render(findings, verdict, target_name, scan_root),
62        OutputFormat::Sarif => sarif::render_with_metadata_and_verdict(
63            findings,
64            target_name,
65            scan_root,
66            rule_metadata,
67            verdict,
68        ),
69        OutputFormat::Html => html::render(findings, verdict, target_name, scan_root),
70    }
71}