pub struct FindingReport { /* private fields */ }Expand description
A set of findings and what the scan that produced them managed to look at.
A lenient read rejects no image, so an empty report means the image is conformant to
what its family’s writer emits and a non-empty one is a list of findings, not a failure.
has_fatal applies a ReadPolicy threshold back
to those findings, and to_json, to_sarif, and
to_table project them for a machine or a person.
A report says through is_truncated when the scan stopped at its
findings cap with the image still unfinished.
§Two serializations, and which is the document
to_json and to_sarif emit documents: a shape
this crate versions through FINDINGS_SCHEMA_VERSION, leading with that version and
with the verdict and count computed from the findings. That is what a consumer parses.
The serde implementation is something else, and deliberately: it serializes the Rust
value as it stands, so a caller embedding a report inside a structure of its own gets the
fields the type has and nothing derived. It carries no schema version, because it is not
the schema. Where the two describe the same thing they agree — a severity and a family
are spelled the same in both — and a Coordinate is a tuple in one and an object in
the other because in one it is a Rust tuple and in the other it is a document field.
Implementations§
Source§impl FindingReport
impl FindingReport
Sourcepub const MAX_FINDINGS: usize = 10_000
pub const MAX_FINDINGS: usize = 10_000
The default of Limits::max_findings: the most
findings one report holds unless a caller names another cap.
A scan reads an image it has no reason to trust, and how many findings that image yields is the image’s own claim: a handful of crafted structures can name the same blocks over and over, and each faulty one is a finding carrying an owned description. The cap is what keeps a report’s memory a property of this crate rather than of the bytes it was pointed at, and it is far past the count anyone reads: a filesystem with ten thousand findings is diagnosed by its first ten.
Sourcepub fn new(findings: Vec<Finding>, truncated: bool, cap: usize) -> Self
pub fn new(findings: Vec<Finding>, truncated: bool, cap: usize) -> Self
A report holding findings, from a scan that ran under cap and stopped early if
truncated.
A family builds one of these from its own taxonomy; nothing else needs to.
Sourcepub fn is_truncated(&self) -> bool
pub fn is_truncated(&self) -> bool
Whether the scan stopped at its findings cap with the image still unfinished.
A truncated report is a floor, not a full accounting: the image holds at least these
findings, and the scan did not look at the rest of it. Everything derived from the
report — worst_severity, has_fatal —
is likewise a floor, and is_clean is false whatever the report
holds, since a scan that stopped short has seen nothing that would let it call an
image clean.
Sourcepub fn is_clean(&self) -> bool
pub fn is_clean(&self) -> bool
Whether the scan looked at the whole image and found nothing.
A truncated report is never clean, however few findings it
holds. The cap can be set low enough that a scan stops before reporting anything —
at zero, before reading a single structure — and an empty report from a scan that
stopped is an absence of looking, not an absence of faults.
Sourcepub fn worst_severity(&self) -> Option<Severity>
pub fn worst_severity(&self) -> Option<Severity>
The severity of the most serious finding, or None when the report is clean.
Sourcepub fn has_fatal(&self, policy: ReadPolicy) -> bool
pub fn has_fatal(&self, policy: ReadPolicy) -> bool
Whether any finding is fatal under policy — the same threshold
ReadPolicy::Strict enforces when opening an image. Under
ReadPolicy::Lenient it is always false.
Sourcepub fn to_json(&self) -> String
pub fn to_json(&self) -> String
Render the report as a JSON object: schema, clean (bool), count, truncated
(bool), and a findings array. A projection computed here, not a stored wire
format.
truncated is always present, true or false: a consumer must be able to tell a
complete report from one that stopped at its findings cap, and an absent field would
read as complete.
The document opens with "schema", holding FINDINGS_SCHEMA_VERSION. A
downstream parser has a contract that no Rust signature describes, so the emitted
shape names its own version rather than leaving a change to be discovered by a parse
failure.
Sourcepub fn to_sarif(&self, artifact_uri: Option<&str>) -> String
pub fn to_sarif(&self, artifact_uri: Option<&str>) -> String
Render the report as a SARIF 2.1.0 log: a single run whose tool is this crate and whose results are the findings, one per finding, for a static-analysis or forensic pipeline that speaks SARIF.
Severity maps onto SARIF’s three actionable levels — structural and integrity
are error, conformance is warning, cosmetic is note — and the exact
severity, family, subsystem, byte offset, and coordinates ride in each result’s
properties, so nothing the level collapse would lose is lost. The coordinates
become a SARIF logical location, and a known byte offset becomes the physical
location’s address. Like to_json, the document is a pure function
of the report — no tool version or timestamp enters it — so identical findings
render identical bytes.
A report that stopped at its findings cap carries a warning-level
toolExecutionNotifications entry saying so, naming the cap that applied, which is
where SARIF records something about the run rather than about the artifact. A
complete report emits no invocations at all, so the document a clean or short scan
renders is unchanged by the cap existing.
artifact_uri, when set, becomes each result’s physical artifact location: a reader
reads an anonymous stream, so the image’s identity is the caller’s to supply. It is
written through unchanged, which makes it a precondition that the string is already
a URI reference as RFC 3986 defines one. A host path is not: a space is not
allowed in a URI at all, and #, ?, and % each mean something else, so a strict
SARIF consumer rejects a document carrying one. Percent-encode a path — every byte
outside A-Z, a-z, 0-9, -, ., _, ~, keeping / — before passing
it here.
Sourcepub fn to_table(&self) -> String
pub fn to_table(&self) -> String
Render the report as a fixed-column human table: a header row, then one line per
finding with its severity, category, location, and detail. A clean report renders a
single no findings line.
A truncated report ends with the notice saying so, whether
or not it holds findings — an empty one is the case where saying so matters most,
since no findings on its own would read as a verdict the scan never reached.
Trait Implementations§
Source§impl Clone for FindingReport
impl Clone for FindingReport
Source§fn clone(&self) -> FindingReport
fn clone(&self) -> FindingReport
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for FindingReport
impl Debug for FindingReport
Source§impl Default for FindingReport
impl Default for FindingReport
Source§impl PartialEq for FindingReport
impl PartialEq for FindingReport
Source§fn eq(&self, other: &FindingReport) -> bool
fn eq(&self, other: &FindingReport) -> bool
self and other values to be equal, and is used by ==.