Skip to main content

keyhog_core/report/
json.rs

1//! Machine-readable JSON reporters: JSON Lines for streams and pretty JSON arrays
2//! for batch output.
3
4use std::io::Write;
5
6use crate::VerifiedFinding;
7
8use super::{ReportError, Reporter};
9
10/// One JSON object per line (JSONL).
11///
12/// # Examples
13///
14/// ```rust
15/// use keyhog_core::JsonlReporter;
16///
17/// let reporter = JsonlReporter::new(Vec::new());
18/// let _ = reporter;
19/// ```
20pub struct JsonlReporter<W: Write> {
21    writer: W,
22}
23
24impl<W: Write> JsonlReporter<W> {
25    /// Create a JSON Lines reporter.
26    ///
27    /// # Examples
28    ///
29    /// ```rust
30    /// use keyhog_core::JsonlReporter;
31    ///
32    /// let reporter = JsonlReporter::new(Vec::new());
33    /// let _ = reporter;
34    /// ```
35    pub fn new(writer: W) -> Self {
36        Self { writer }
37    }
38}
39
40impl<W: Write> Reporter for JsonlReporter<W> {
41    fn report(&mut self, finding: &VerifiedFinding) -> Result<(), ReportError> {
42        serde_json::to_writer(&mut self.writer, finding)?;
43        writeln!(self.writer)?;
44        Ok(())
45    }
46
47    fn finish(&mut self) -> Result<(), ReportError> {
48        self.writer.flush()?;
49        Ok(())
50    }
51}
52
53/// Full JSON array output.
54///
55/// # Examples
56///
57/// ```rust
58/// use keyhog_core::JsonReporter;
59///
60/// let reporter = JsonReporter::new(Vec::new());
61/// let _ = reporter;
62/// ```
63pub struct JsonReporter<W: Write> {
64    writer: W,
65    findings: Vec<VerifiedFinding>,
66}
67
68impl<W: Write> JsonReporter<W> {
69    /// Create a JSON array reporter.
70    ///
71    /// # Examples
72    ///
73    /// ```rust
74    /// use keyhog_core::JsonReporter;
75    ///
76    /// let reporter = JsonReporter::new(Vec::new());
77    /// let _ = reporter;
78    /// ```
79    pub fn new(writer: W) -> Self {
80        Self {
81            writer,
82            findings: Vec::new(),
83        }
84    }
85}
86
87impl<W: Write> Reporter for JsonReporter<W> {
88    fn report(&mut self, finding: &VerifiedFinding) -> Result<(), ReportError> {
89        self.findings.push(finding.clone());
90        Ok(())
91    }
92
93    fn finish(&mut self) -> Result<(), ReportError> {
94        serde_json::to_writer_pretty(&mut self.writer, &self.findings)?;
95        writeln!(self.writer)?;
96        Ok(())
97    }
98}