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, WriterBackedReporter};
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 + Send> {
21    writer: W,
22}
23
24impl<W: Write + Send> 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 + Send> 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.flush_writer()
49    }
50}
51
52impl<W: Write + Send> WriterBackedReporter for JsonlReporter<W> {
53    type Writer = W;
54
55    fn writer_mut(&mut self) -> &mut Self::Writer {
56        &mut self.writer
57    }
58}
59
60/// Full JSON array output.
61///
62/// # Examples
63///
64/// ```rust
65/// use keyhog_core::JsonArrayReporter;
66///
67/// let reporter = JsonArrayReporter::new(Vec::new()).unwrap();
68/// let _ = reporter;
69/// ```
70pub struct JsonArrayReporter<W: Write + Send> {
71    writer: W,
72    first: bool,
73}
74
75impl<W: Write + Send> JsonArrayReporter<W> {
76    /// Create a JSON array reporter.
77    ///
78    /// # Examples
79    ///
80    /// ```rust
81    /// use keyhog_core::JsonArrayReporter;
82    ///
83    /// let reporter = JsonArrayReporter::new(Vec::new()).unwrap();
84    /// let _ = reporter;
85    /// ```
86    pub fn new(mut writer: W) -> Result<Self, ReportError> {
87        write!(writer, "[")?;
88        Ok(Self {
89            writer,
90            first: true,
91        })
92    }
93}
94
95impl<W: Write + Send> Reporter for JsonArrayReporter<W> {
96    fn report(&mut self, finding: &VerifiedFinding) -> Result<(), ReportError> {
97        if !self.first {
98            write!(self.writer, ",")?;
99        }
100        serde_json::to_writer(&mut self.writer, finding)?;
101        self.first = false;
102        Ok(())
103    }
104
105    fn finish(&mut self) -> Result<(), ReportError> {
106        write!(self.writer, "]")?;
107        self.flush_writer()
108    }
109}
110
111impl<W: Write + Send> WriterBackedReporter for JsonArrayReporter<W> {
112    type Writer = W;
113
114    fn writer_mut(&mut self) -> &mut Self::Writer {
115        &mut self.writer
116    }
117}
118
119/// Alias for [`JsonArrayReporter`] for standard JSON output.
120pub type JsonReporter<W> = JsonArrayReporter<W>;