pub struct SensorReportBuilder { /* private fields */ }Expand description
Builder for constructing a SensorReport from a PerfgateReport.
This builder provides a fluent API for constructing sensor reports suitable for cockpit integration. It handles:
- Mapping verdict status (Pass/Warn/Fail) to sensor vocabulary (Pass/Warn/Error)
- Generating fingerprints for findings
- Truncating findings when limits are exceeded
- Aggregating multiple bench outcomes
- Sorting artifacts deterministically
§Example
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::{ToolInfo, PerfgateReport, VerdictStatus, Verdict, VerdictCounts, ReportSummary, REPORT_SCHEMA_V1};
let tool = ToolInfo {
name: "perfgate".to_string(),
version: "0.1.0".to_string(),
};
let report = PerfgateReport {
report_type: REPORT_SCHEMA_V1.to_string(),
verdict: Verdict {
status: VerdictStatus::Pass,
counts: VerdictCounts { pass: 2, warn: 0, fail: 0 },
reasons: vec![],
},
compare: None,
findings: vec![],
summary: ReportSummary { pass_count: 2, warn_count: 0, fail_count: 0, total_count: 2 },
};
let sensor_report = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.ended_at("2024-01-01T00:01:00Z".to_string(), 60000)
.baseline(true, None)
.artifact("report.json".to_string(), "sensor_report".to_string())
.build(&report);
assert_eq!(sensor_report.verdict.status, perfgate_types::SensorVerdictStatus::Pass);
assert_eq!(sensor_report.verdict.counts.info, 2);Implementations§
Source§impl SensorReportBuilder
impl SensorReportBuilder
Sourcepub fn new(tool: ToolInfo, started_at: String) -> SensorReportBuilder
pub fn new(tool: ToolInfo, started_at: String) -> SensorReportBuilder
Create a new SensorReportBuilder.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string());Sourcepub fn ended_at(self, ended_at: String, duration_ms: u64) -> SensorReportBuilder
pub fn ended_at(self, ended_at: String, duration_ms: u64) -> SensorReportBuilder
Set the end time and duration.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.ended_at("2024-01-01T00:01:00Z".to_string(), 60000);Sourcepub fn baseline(
self,
available: bool,
reason: Option<String>,
) -> SensorReportBuilder
pub fn baseline( self, available: bool, reason: Option<String>, ) -> SensorReportBuilder
Set baseline availability.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
// Baseline available
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.baseline(true, None);Sourcepub fn engine(self, capability: Capability) -> SensorReportBuilder
pub fn engine(self, capability: Capability) -> SensorReportBuilder
Set engine capability explicitly.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::{ToolInfo, Capability, CapabilityStatus};
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.engine(Capability {
status: CapabilityStatus::Available,
reason: None,
});Sourcepub fn artifact(
self,
path: String,
artifact_type: String,
) -> SensorReportBuilder
pub fn artifact( self, path: String, artifact_type: String, ) -> SensorReportBuilder
Add an artifact.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.artifact("report.json".to_string(), "sensor_report".to_string());Sourcepub fn max_findings(self, limit: usize) -> SensorReportBuilder
pub fn max_findings(self, limit: usize) -> SensorReportBuilder
Set the maximum number of findings to include.
When exceeded, findings are truncated and a meta-finding is appended.
findings_emitted in the output counts real findings only (excluding the truncation meta-finding).
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.max_findings(50);Sourcepub fn take_artifacts(&mut self) -> Vec<SensorArtifact>
pub fn take_artifacts(&mut self) -> Vec<SensorArtifact>
Take ownership of accumulated artifacts (for manual report building).
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::ToolInfo;
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let mut builder = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.artifact("report.json".to_string(), "sensor_report".to_string());
let artifacts = builder.take_artifacts();
assert_eq!(artifacts.len(), 1);
assert_eq!(artifacts[0].path, "report.json");Sourcepub fn build(self, report: &PerfgateReport) -> SensorReport
pub fn build(self, report: &PerfgateReport) -> SensorReport
Build the SensorReport from a PerfgateReport.
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::{
ToolInfo, PerfgateReport, VerdictStatus, Verdict, VerdictCounts,
ReportSummary, SensorVerdictStatus, REPORT_SCHEMA_V1,
};
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let report = PerfgateReport {
report_type: REPORT_SCHEMA_V1.to_string(),
verdict: Verdict {
status: VerdictStatus::Pass,
counts: VerdictCounts { pass: 1, warn: 0, fail: 0 },
reasons: vec![],
},
compare: None,
findings: vec![],
summary: ReportSummary {
pass_count: 1, warn_count: 0, fail_count: 0, total_count: 1,
},
};
let sensor = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.ended_at("2024-01-01T00:01:00Z".to_string(), 60000)
.baseline(true, None)
.build(&report);
assert_eq!(sensor.verdict.status, SensorVerdictStatus::Pass);
assert_eq!(sensor.verdict.counts.info, 1);Sourcepub fn build_error(
self,
error_message: &str,
stage: &str,
error_kind: &str,
) -> SensorReport
pub fn build_error( self, error_message: &str, stage: &str, error_kind: &str, ) -> SensorReport
Build an error SensorReport for catastrophic failures.
This creates a report when the sensor itself failed to run properly.
stage indicates which phase failed (e.g. “config_parse”, “run_command”).
error_kind classifies the error (e.g. “io_error”, “parse_error”, “exec_error”).
§Examples
use perfgate_sensor::SensorReportBuilder;
use perfgate_types::{ToolInfo, SensorVerdictStatus};
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let sensor = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.build_error("config not found", "config_parse", "parse_error");
assert_eq!(sensor.verdict.status, SensorVerdictStatus::Fail);
assert_eq!(sensor.verdict.counts.error, 1);
assert_eq!(sensor.findings.len(), 1);Sourcepub fn build_aggregated(
self,
outcomes: &[BenchOutcome],
) -> (SensorReport, String)
pub fn build_aggregated( self, outcomes: &[BenchOutcome], ) -> (SensorReport, String)
Build an aggregated SensorReport from multiple bench outcomes.
This encapsulates the multi-bench cockpit aggregation logic:
- Maps findings from each bench’s
PerfgateReportto sensor findings - In multi-bench mode: prefixes messages with
[bench_name], injectsbench_nameinto finding data, includes bench_name in fingerprint seed - Aggregates counts (sum), verdict (worst-of), reasons (union/deduped)
- Registers per-bench artifacts
- Combines markdown with
\n---\n\nseparator in multi-bench - Applies truncation via
truncate_findings()usingself.max_findings - Returns
(SensorReport, combined_markdown)
§Examples
use perfgate_sensor::{SensorReportBuilder, BenchOutcome};
use perfgate_types::{
ToolInfo, PerfgateReport, VerdictStatus, Verdict, VerdictCounts,
ReportSummary, SensorVerdictStatus, REPORT_SCHEMA_V1,
};
let tool = ToolInfo { name: "perfgate".to_string(), version: "0.1.0".to_string() };
let report = PerfgateReport {
report_type: REPORT_SCHEMA_V1.to_string(),
verdict: Verdict {
status: VerdictStatus::Pass,
counts: VerdictCounts { pass: 1, warn: 0, fail: 0 },
reasons: vec![],
},
compare: None,
findings: vec![],
summary: ReportSummary {
pass_count: 1, warn_count: 0, fail_count: 0, total_count: 1,
},
};
let outcome = BenchOutcome::Success {
bench_name: "my-bench".to_string(),
report,
has_compare: false,
baseline_available: false,
markdown: "## Results\n".to_string(),
extras_prefix: "extras".to_string(),
};
let (sensor, markdown) = SensorReportBuilder::new(tool, "2024-01-01T00:00:00Z".to_string())
.build_aggregated(&[outcome]);
assert_eq!(sensor.verdict.status, SensorVerdictStatus::Pass);
assert!(markdown.contains("Results"));Auto Trait Implementations§
impl Freeze for SensorReportBuilder
impl RefUnwindSafe for SensorReportBuilder
impl Send for SensorReportBuilder
impl Sync for SensorReportBuilder
impl Unpin for SensorReportBuilder
impl UnsafeUnpin for SensorReportBuilder
impl UnwindSafe for SensorReportBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.