1use crate::format::Format;
2use crate::models::GenericFinding;
3use secfinding::{Finding, Reportable};
4use std::io::Write;
5
6pub mod json;
7pub mod markdown;
8pub mod summary;
9
10pub fn render_any<R: Reportable>(
12 findings: &[R],
13 format: Format,
14 tool_name: &str,
15) -> Result<String, serde_json::Error> {
16 let generic: Vec<GenericFinding> = findings
17 .iter()
18 .map(GenericFinding::try_from_reportable)
19 .collect::<Result<_, _>>()?;
20
21 match format {
22 Format::Text => Ok(summary::render_text_generic(&generic)),
23 Format::Json => json::render_json_generic(&generic),
24 Format::Jsonl => json::render_jsonl_generic(&generic),
25 Format::Sarif => json::render_sarif_generic(&generic, tool_name),
26 Format::Markdown => Ok(markdown::render_markdown_generic(&generic, tool_name)),
27 }
28}
29
30pub fn render(
32 findings: &[Finding],
33 format: Format,
34 tool_name: &str,
35) -> Result<String, serde_json::Error> {
36 render_any(findings, format, tool_name)
37}
38
39pub fn emit(content: &str, mut writer: impl Write) -> std::io::Result<()> {
41 write!(writer, "{}", content)
42}