use parlov_core::{EndpointVerdict, OracleResult};
use crate::sarif_builder::{
build_rule, build_sarif_document, build_sarif_result, build_verdict_run_properties,
deduplicate_rules, findings_to_results, ResultContext,
};
use crate::ScanFinding;
pub fn render_sarif(
target_url: &str,
result: &OracleResult,
strategy_id: &str,
method: &str,
) -> Result<String, serde_json::Error> {
let rules = deduplicate_rules(vec![build_rule(result)]);
let ctx = ResultContext {
target_url,
result,
strategy_id,
method,
};
let results: Vec<_> = build_sarif_result(&ctx).into_iter().collect();
let doc = build_sarif_document(rules, results, None);
serde_json::to_string_pretty(&doc)
}
pub fn render_scan_sarif(
target_url: &str,
findings: &[ScanFinding],
) -> Result<String, serde_json::Error> {
use serde_sarif::sarif::PropertyBag;
use std::collections::BTreeMap;
let rules = deduplicate_rules(findings.iter().map(|f| build_rule(&f.result)).collect());
let results = findings_to_results(target_url, findings, None);
let mut props = BTreeMap::new();
props.insert("target_url".to_owned(), serde_json::json!(target_url));
let run_props = PropertyBag::builder().additional_properties(props).build();
let doc = build_sarif_document(rules, results, Some(run_props));
serde_json::to_string_pretty(&doc)
}
pub fn render_endpoint_verdict_sarif(
target_url: &str,
verdict: &EndpointVerdict,
findings: &[ScanFinding],
) -> Result<String, serde_json::Error> {
let rules = deduplicate_rules(findings.iter().map(|f| build_rule(&f.result)).collect());
let results = findings_to_results(target_url, findings, Some(verdict));
let run_props = build_verdict_run_properties(target_url, verdict);
let doc = build_sarif_document(rules, results, Some(run_props));
serde_json::to_string_pretty(&doc)
}
#[cfg(test)]
#[path = "sarif_tests.rs"]
mod tests;