Skip to main content

provenant/models/
output.rs

1use super::{FileInfo, Match, Package, TopLevelDependency};
2use serde::{Deserialize, Serialize};
3use serde_json::{Map, Value};
4
5pub const OUTPUT_FORMAT_VERSION: &str = "4.1.0";
6pub const TOOL_NAME: &str = "provenant";
7pub const HEADER_NOTICE: &str = "Generated with Provenant and provided on an \"AS IS\" basis, without warranties or conditions of any kind, either express or implied. Provenant and its authors/providers do not provide legal advice, and are not responsible for how this output is used. Consult qualified legal counsel for legal advice.";
8
9#[derive(Debug)]
10/// Top-level ScanCode-compatible JSON payload.
11pub struct Output {
12    pub summary: Option<Summary>,
13    pub tallies: Option<Tallies>,
14    pub tallies_of_key_files: Option<Tallies>,
15    pub tallies_by_facet: Option<Vec<FacetTallies>>,
16    pub headers: Vec<Header>,
17    pub packages: Vec<Package>,
18    pub dependencies: Vec<TopLevelDependency>,
19    pub license_detections: Vec<TopLevelLicenseDetection>,
20    pub files: Vec<FileInfo>,
21    pub license_references: Vec<LicenseReference>,
22    pub license_rule_references: Vec<LicenseRuleReference>,
23}
24
25#[derive(Deserialize, Debug, Clone, PartialEq)]
26pub struct TopLevelLicenseDetection {
27    pub identifier: String,
28    pub license_expression: String,
29    pub license_expression_spdx: String,
30    pub detection_count: usize,
31    #[serde(default)]
32    pub detection_log: Vec<String>,
33    pub reference_matches: Vec<Match>,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct Summary {
38    pub declared_license_expression: Option<String>,
39    pub license_clarity_score: Option<LicenseClarityScore>,
40    pub declared_holder: Option<String>,
41    pub primary_language: Option<String>,
42    pub other_license_expressions: Vec<TallyEntry>,
43    pub other_holders: Vec<TallyEntry>,
44    pub other_languages: Vec<TallyEntry>,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq)]
48pub struct LicenseClarityScore {
49    pub score: usize,
50    pub declared_license: bool,
51    pub identification_precision: bool,
52    pub has_license_text: bool,
53    pub declared_copyrights: bool,
54    pub conflicting_license_categories: bool,
55    pub ambiguous_compound_licensing: bool,
56}
57
58#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
59pub struct TallyEntry {
60    pub value: Option<String>,
61    pub count: usize,
62}
63
64#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
65pub struct Tallies {
66    #[serde(default, skip_serializing_if = "Vec::is_empty")]
67    pub detected_license_expression: Vec<TallyEntry>,
68    #[serde(default, skip_serializing_if = "Vec::is_empty")]
69    pub copyrights: Vec<TallyEntry>,
70    #[serde(default, skip_serializing_if = "Vec::is_empty")]
71    pub holders: Vec<TallyEntry>,
72    #[serde(default, skip_serializing_if = "Vec::is_empty")]
73    pub authors: Vec<TallyEntry>,
74    #[serde(default, skip_serializing_if = "Vec::is_empty")]
75    pub programming_language: Vec<TallyEntry>,
76}
77
78impl Tallies {
79    pub fn is_empty(&self) -> bool {
80        self.detected_license_expression.is_empty()
81            && self.copyrights.is_empty()
82            && self.holders.is_empty()
83            && self.authors.is_empty()
84            && self.programming_language.is_empty()
85    }
86}
87
88#[derive(Debug, Clone, PartialEq, Eq)]
89pub struct FacetTallies {
90    pub facet: String,
91    pub tallies: Tallies,
92}
93
94#[derive(Debug)]
95/// Scan execution metadata stored in `output.headers`.
96pub struct Header {
97    pub tool_name: String,
98    pub tool_version: String,
99    pub options: Map<String, Value>,
100    pub notice: String,
101    pub start_timestamp: String,
102    pub end_timestamp: String,
103    pub output_format_version: String,
104    pub duration: f64,
105    pub errors: Vec<String>,
106    pub warnings: Vec<String>,
107    pub extra_data: ExtraData,
108}
109
110#[derive(Debug)]
111/// Additional counters and environment details for a scan run.
112pub struct ExtraData {
113    pub system_environment: SystemEnvironment,
114    pub spdx_license_list_version: String,
115    pub files_count: usize,
116    pub directories_count: usize,
117    pub excluded_count: usize,
118}
119
120#[derive(Debug)]
121/// Host environment information captured during scan execution.
122pub struct SystemEnvironment {
123    pub operating_system: String,
124    pub cpu_architecture: String,
125    pub platform: String,
126    pub platform_version: String,
127    pub rust_version: String,
128}
129
130#[derive(Deserialize, Debug)]
131/// Reference entry for a detected license.
132pub struct LicenseReference {
133    #[serde(default)]
134    pub key: Option<String>,
135    #[serde(default)]
136    pub language: Option<String>,
137    pub name: String,
138    pub short_name: String,
139    #[serde(default)]
140    pub owner: Option<String>,
141    #[serde(default)]
142    pub homepage_url: Option<String>,
143    pub spdx_license_key: String,
144    #[serde(default)]
145    pub other_spdx_license_keys: Vec<String>,
146    #[serde(default)]
147    pub osi_license_key: Option<String>,
148    #[serde(default)]
149    pub text_urls: Vec<String>,
150    #[serde(default)]
151    pub osi_url: Option<String>,
152    #[serde(default)]
153    pub faq_url: Option<String>,
154    #[serde(default)]
155    pub other_urls: Vec<String>,
156    #[serde(default)]
157    pub category: Option<String>,
158    #[serde(default)]
159    pub is_exception: bool,
160    #[serde(default)]
161    pub is_unknown: bool,
162    #[serde(default)]
163    pub is_generic: bool,
164    #[serde(default)]
165    pub notes: Option<String>,
166    #[serde(default)]
167    pub minimum_coverage: Option<u8>,
168    #[serde(default)]
169    pub standard_notice: Option<String>,
170    #[serde(default)]
171    pub ignorable_copyrights: Vec<String>,
172    #[serde(default)]
173    pub ignorable_holders: Vec<String>,
174    #[serde(default)]
175    pub ignorable_authors: Vec<String>,
176    #[serde(default)]
177    pub ignorable_urls: Vec<String>,
178    #[serde(default)]
179    pub ignorable_emails: Vec<String>,
180    #[serde(default)]
181    pub scancode_url: Option<String>,
182    #[serde(default)]
183    pub licensedb_url: Option<String>,
184    #[serde(default)]
185    pub spdx_url: Option<String>,
186    pub text: String,
187}
188
189#[derive(Deserialize, Debug)]
190/// Reference metadata for a license detection rule.
191pub struct LicenseRuleReference {
192    pub identifier: String,
193    pub license_expression: String,
194    pub is_license_text: bool,
195    pub is_license_notice: bool,
196    pub is_license_reference: bool,
197    pub is_license_tag: bool,
198    pub is_license_clue: bool,
199    pub is_license_intro: bool,
200    #[serde(default)]
201    pub language: Option<String>,
202    #[serde(default)]
203    pub rule_url: Option<String>,
204    #[serde(default)]
205    pub is_required_phrase: bool,
206    #[serde(default)]
207    pub skip_for_required_phrase_generation: bool,
208    #[serde(default)]
209    pub replaced_by: Vec<String>,
210    #[serde(default)]
211    pub is_continuous: bool,
212    #[serde(default)]
213    pub is_synthetic: bool,
214    #[serde(default)]
215    pub is_from_license: bool,
216    #[serde(default)]
217    pub length: usize,
218    #[serde(default)]
219    pub relevance: Option<u8>,
220    #[serde(default)]
221    pub minimum_coverage: Option<u8>,
222    #[serde(default)]
223    pub referenced_filenames: Vec<String>,
224    #[serde(default)]
225    pub notes: Option<String>,
226    #[serde(default)]
227    pub ignorable_copyrights: Vec<String>,
228    #[serde(default)]
229    pub ignorable_holders: Vec<String>,
230    #[serde(default)]
231    pub ignorable_authors: Vec<String>,
232    #[serde(default)]
233    pub ignorable_urls: Vec<String>,
234    #[serde(default)]
235    pub ignorable_emails: Vec<String>,
236    #[serde(default)]
237    pub text: Option<String>,
238}