ruso_runtime/runtime/
report.rs1use crate::contract::Severity;
2use crate::runtime::spec::CheckMetadata;
3
4#[derive(Debug, Clone)]
8pub struct Finding {
9 pub name: String,
11 pub description: Option<String>,
13 pub impact: Option<String>,
15 pub severity: Severity,
17 pub author: Option<String>,
19 pub cve: Vec<String>,
21 pub cwe: Vec<String>,
23 pub references: Vec<String>,
25 pub cvss: Vec<String>,
27 pub cvss_score: Vec<String>,
29 pub mitigation: Option<String>,
31 pub evidence: Vec<String>,
33}
34
35impl Finding {
36 pub fn from_metadata(metadata: &CheckMetadata, evidence: Vec<String>) -> Option<Self> {
38 let name = metadata.name.clone()?;
39 Some(Self {
40 name,
41 description: metadata.description.clone(),
42 impact: metadata.impact.clone(),
43 severity: metadata.severity.clone().unwrap_or(Severity::Info),
44 author: metadata.author.clone(),
45 cve: metadata.cve.clone(),
46 cwe: metadata.cwe.clone(),
47 references: metadata.references.clone(),
48 cvss: metadata.cvss.clone(),
49 cvss_score: metadata.cvss_score.clone(),
50 mitigation: metadata.mitigation.clone(),
51 evidence,
52 })
53 }
54}
55
56#[derive(Debug, Clone, Default)]
59pub struct Report {
60 pub findings: Vec<Finding>,
62}
63
64impl Report {
65 pub fn set_finding(&mut self, finding: Finding) {
67 self.findings.clear();
68 self.findings.push(finding);
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::contract::Severity;
75 use crate::runtime::spec::CheckMetadata;
76
77 use super::Finding;
78
79 #[test]
80 fn from_metadata_requires_name() {
81 let meta = CheckMetadata {
82 name: Some("Check".into()),
83 description: Some("desc".into()),
84 severity: Some(Severity::Medium),
85 ..Default::default()
86 };
87 let finding = Finding::from_metadata(&meta, vec!["proof".into()]).expect("finding");
88 assert_eq!(finding.name, "Check");
89 assert_eq!(finding.severity, Severity::Medium);
90 assert_eq!(finding.evidence, vec!["proof"]);
91 }
92
93 #[test]
94 fn from_metadata_without_name_is_none() {
95 let meta = CheckMetadata {
96 description: Some("desc".into()),
97 ..Default::default()
98 };
99 assert!(Finding::from_metadata(&meta, vec![]).is_none());
100 }
101}