Skip to main content

provenant/output_schema/
package_data.rs

1// SPDX-FileCopyrightText: Provenant contributors
2// SPDX-License-Identifier: Apache-2.0
3
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7use super::datasource_id::OutputDatasourceId;
8use super::dependency::OutputDependency;
9use super::file_reference::OutputFileReference;
10use super::license_detection::OutputLicenseDetection;
11use super::package_type::OutputPackageType;
12use super::party::OutputParty;
13use super::serde_helpers::serialize_optional_map_as_object;
14
15#[derive(Serialize, Deserialize, Debug, Clone, Default)]
16pub struct OutputPackageData {
17    #[serde(rename = "type")]
18    pub package_type: Option<OutputPackageType>,
19    pub namespace: Option<String>,
20    pub name: Option<String>,
21    pub version: Option<String>,
22    #[serde(default, serialize_with = "serialize_optional_map_as_object")]
23    pub qualifiers: Option<HashMap<String, String>>,
24    pub subpath: Option<String>,
25    pub primary_language: Option<String>,
26    pub description: Option<String>,
27    pub release_date: Option<String>,
28    #[serde(default)]
29    pub parties: Vec<OutputParty>,
30    #[serde(default)]
31    pub keywords: Vec<String>,
32    pub homepage_url: Option<String>,
33    pub download_url: Option<String>,
34    pub size: Option<u64>,
35    pub sha1: Option<String>,
36    pub md5: Option<String>,
37    pub sha256: Option<String>,
38    pub sha512: Option<String>,
39    pub bug_tracking_url: Option<String>,
40    pub code_view_url: Option<String>,
41    pub vcs_url: Option<String>,
42    pub copyright: Option<String>,
43    pub holder: Option<String>,
44    pub declared_license_expression: Option<String>,
45    pub declared_license_expression_spdx: Option<String>,
46    #[serde(default)]
47    pub license_detections: Vec<OutputLicenseDetection>,
48    pub other_license_expression: Option<String>,
49    pub other_license_expression_spdx: Option<String>,
50    #[serde(default)]
51    pub other_license_detections: Vec<OutputLicenseDetection>,
52    pub extracted_license_statement: Option<String>,
53    pub notice_text: Option<String>,
54    #[serde(default)]
55    pub source_packages: Vec<String>,
56    #[serde(default)]
57    pub file_references: Vec<OutputFileReference>,
58    #[serde(default)]
59    pub is_private: bool,
60    #[serde(default)]
61    pub is_virtual: bool,
62    #[serde(default, serialize_with = "serialize_optional_map_as_object")]
63    pub extra_data: Option<HashMap<String, serde_json::Value>>,
64    #[serde(default)]
65    pub dependencies: Vec<OutputDependency>,
66    pub repository_homepage_url: Option<String>,
67    pub repository_download_url: Option<String>,
68    pub api_data_url: Option<String>,
69    pub datasource_id: Option<OutputDatasourceId>,
70    pub purl: Option<String>,
71}
72
73impl From<&crate::models::PackageData> for OutputPackageData {
74    fn from(value: &crate::models::PackageData) -> Self {
75        Self {
76            package_type: value.package_type.map(OutputPackageType::from),
77            namespace: value.namespace.clone(),
78            name: value.name.clone(),
79            version: value.version.clone(),
80            qualifiers: value.qualifiers.clone(),
81            subpath: value.subpath.clone(),
82            primary_language: value.primary_language.clone(),
83            description: value.description.clone(),
84            release_date: value.release_date.clone(),
85            parties: value.parties.iter().map(OutputParty::from).collect(),
86            keywords: value.keywords.clone(),
87            homepage_url: value.homepage_url.clone(),
88            download_url: value.download_url.clone(),
89            size: value.size,
90            sha1: value.sha1.as_ref().map(|d| d.as_hex()),
91            md5: value.md5.as_ref().map(|d| d.as_hex()),
92            sha256: value.sha256.as_ref().map(|d| d.as_hex()),
93            sha512: value.sha512.as_ref().map(|d| d.as_hex()),
94            bug_tracking_url: value.bug_tracking_url.clone(),
95            code_view_url: value.code_view_url.clone(),
96            vcs_url: value.vcs_url.clone(),
97            copyright: value.copyright.clone(),
98            holder: value.holder.clone(),
99            declared_license_expression: value.declared_license_expression.clone(),
100            declared_license_expression_spdx: value.declared_license_expression_spdx.clone(),
101            license_detections: value
102                .license_detections
103                .iter()
104                .map(OutputLicenseDetection::from)
105                .collect(),
106            other_license_expression: value.other_license_expression.clone(),
107            other_license_expression_spdx: value.other_license_expression_spdx.clone(),
108            other_license_detections: value
109                .other_license_detections
110                .iter()
111                .map(OutputLicenseDetection::from)
112                .collect(),
113            extracted_license_statement: value.extracted_license_statement.clone(),
114            notice_text: value.notice_text.clone(),
115            source_packages: value.source_packages.clone(),
116            file_references: value
117                .file_references
118                .iter()
119                .map(OutputFileReference::from)
120                .collect(),
121            is_private: value.is_private,
122            is_virtual: value.is_virtual,
123            extra_data: value.extra_data.clone(),
124            dependencies: value
125                .dependencies
126                .iter()
127                .map(OutputDependency::from)
128                .collect(),
129            repository_homepage_url: value.repository_homepage_url.clone(),
130            repository_download_url: value.repository_download_url.clone(),
131            api_data_url: value.api_data_url.clone(),
132            datasource_id: value.datasource_id.map(OutputDatasourceId::from),
133            purl: value.purl.clone(),
134        }
135    }
136}
137
138impl TryFrom<&OutputPackageData> for crate::models::PackageData {
139    type Error = String;
140    fn try_from(value: &OutputPackageData) -> Result<Self, Self::Error> {
141        let mut parties = Vec::with_capacity(value.parties.len());
142        for p in &value.parties {
143            parties.push(crate::models::Party::try_from(p)?);
144        }
145        let mut license_detections = Vec::with_capacity(value.license_detections.len());
146        for d in &value.license_detections {
147            license_detections.push(crate::models::LicenseDetection::try_from(d)?);
148        }
149        let mut other_license_detections = Vec::with_capacity(value.other_license_detections.len());
150        for d in &value.other_license_detections {
151            other_license_detections.push(crate::models::LicenseDetection::try_from(d)?);
152        }
153        let mut file_references = Vec::with_capacity(value.file_references.len());
154        for f in &value.file_references {
155            file_references.push(crate::models::FileReference::try_from(f)?);
156        }
157        let mut dependencies = Vec::with_capacity(value.dependencies.len());
158        for d in &value.dependencies {
159            dependencies.push(crate::models::Dependency::try_from(d)?);
160        }
161        Ok(Self {
162            package_type: value
163                .package_type
164                .as_ref()
165                .map(crate::models::PackageType::try_from)
166                .transpose()?,
167            namespace: value.namespace.clone(),
168            name: value.name.clone(),
169            version: value.version.clone(),
170            qualifiers: value.qualifiers.clone(),
171            subpath: value.subpath.clone(),
172            primary_language: value.primary_language.clone(),
173            description: value.description.clone(),
174            release_date: value.release_date.clone(),
175            parties,
176            keywords: value.keywords.clone(),
177            homepage_url: value.homepage_url.clone(),
178            download_url: value.download_url.clone(),
179            size: value.size,
180            sha1: value
181                .sha1
182                .as_ref()
183                .map(|s| crate::models::Sha1Digest::from_hex(s))
184                .transpose()
185                .map_err(|e| format!("invalid sha1: {}", e))?,
186            md5: value
187                .md5
188                .as_ref()
189                .map(|s| crate::models::Md5Digest::from_hex(s))
190                .transpose()
191                .map_err(|e| format!("invalid md5: {}", e))?,
192            sha256: value
193                .sha256
194                .as_ref()
195                .map(|s| crate::models::Sha256Digest::from_hex(s))
196                .transpose()
197                .map_err(|e| format!("invalid sha256: {}", e))?,
198            sha512: value
199                .sha512
200                .as_ref()
201                .map(|s| crate::models::Sha512Digest::from_hex(s))
202                .transpose()
203                .map_err(|e| format!("invalid sha512: {}", e))?,
204            bug_tracking_url: value.bug_tracking_url.clone(),
205            code_view_url: value.code_view_url.clone(),
206            vcs_url: value.vcs_url.clone(),
207            copyright: value.copyright.clone(),
208            holder: value.holder.clone(),
209            declared_license_expression: value.declared_license_expression.clone(),
210            declared_license_expression_spdx: value.declared_license_expression_spdx.clone(),
211            license_detections,
212            other_license_expression: value.other_license_expression.clone(),
213            other_license_expression_spdx: value.other_license_expression_spdx.clone(),
214            other_license_detections,
215            extracted_license_statement: value.extracted_license_statement.clone(),
216            notice_text: value.notice_text.clone(),
217            source_packages: value.source_packages.clone(),
218            file_references,
219            is_private: value.is_private,
220            is_virtual: value.is_virtual,
221            extra_data: value.extra_data.clone(),
222            dependencies,
223            repository_homepage_url: value.repository_homepage_url.clone(),
224            repository_download_url: value.repository_download_url.clone(),
225            api_data_url: value.api_data_url.clone(),
226            datasource_id: value
227                .datasource_id
228                .as_ref()
229                .map(crate::models::DatasourceId::try_from)
230                .transpose()?,
231            purl: value.purl.clone(),
232        })
233    }
234}