kql_panopticon/execution/reporting/
output.rs

1//! Reporting step output types
2//!
3//! Defines the output structure for reporting steps.
4
5use crate::pack::ReportFormat;
6use std::path::PathBuf;
7use std::time::Duration;
8
9/// Output from a reporting step execution
10#[derive(Debug, Clone)]
11pub struct ReportingStepOutput {
12    /// Report name
13    name: String,
14
15    /// Path where report was written
16    path: PathBuf,
17
18    /// Report format
19    format: ReportFormat,
20
21    /// Byte count
22    byte_count: usize,
23
24    /// Line count (for text formats)
25    line_count: Option<usize>,
26
27    /// Execution duration
28    duration: Duration,
29}
30
31impl ReportingStepOutput {
32    /// Create a new reporting output
33    pub fn new(
34        name: impl Into<String>,
35        path: PathBuf,
36        format: ReportFormat,
37        byte_count: usize,
38        line_count: Option<usize>,
39        duration: Duration,
40    ) -> Self {
41        Self {
42            name: name.into(),
43            path,
44            format,
45            byte_count,
46            line_count,
47            duration,
48        }
49    }
50
51    /// Get report name
52    pub fn name(&self) -> &str {
53        &self.name
54    }
55
56    /// Get output path
57    pub fn path(&self) -> &PathBuf {
58        &self.path
59    }
60
61    /// Get report format
62    pub fn format(&self) -> ReportFormat {
63        self.format
64    }
65
66    /// Get byte count
67    pub fn byte_count(&self) -> usize {
68        self.byte_count
69    }
70
71    /// Get line count
72    pub fn line_count(&self) -> Option<usize> {
73        self.line_count
74    }
75
76    /// Get execution duration
77    pub fn duration(&self) -> Duration {
78        self.duration
79    }
80
81    /// Get duration in milliseconds
82    pub fn duration_ms(&self) -> u64 {
83        self.duration.as_millis() as u64
84    }
85}
86
87/// Summary of a generated report
88#[derive(Debug, Clone)]
89pub struct GeneratedReport {
90    pub name: String,
91    pub path: PathBuf,
92    pub format: ReportFormat,
93    pub byte_count: usize,
94}
95
96impl From<ReportingStepOutput> for GeneratedReport {
97    fn from(output: ReportingStepOutput) -> Self {
98        Self {
99            name: output.name,
100            path: output.path,
101            format: output.format,
102            byte_count: output.byte_count,
103        }
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_reporting_output() {
113        let output = ReportingStepOutput::new(
114            "summary",
115            PathBuf::from("/tmp/summary.md"),
116            ReportFormat::Markdown,
117            1024,
118            Some(50),
119            Duration::from_millis(100),
120        );
121
122        assert_eq!(output.name(), "summary");
123        assert_eq!(output.byte_count(), 1024);
124        assert_eq!(output.line_count(), Some(50));
125        assert_eq!(output.duration_ms(), 100);
126    }
127
128    #[test]
129    fn test_generated_report_conversion() {
130        let output = ReportingStepOutput::new(
131            "report",
132            PathBuf::from("/tmp/report.md"),
133            ReportFormat::Markdown,
134            512,
135            None,
136            Duration::from_millis(50),
137        );
138
139        let report: GeneratedReport = output.into();
140        assert_eq!(report.name, "report");
141        assert_eq!(report.byte_count, 512);
142    }
143}