Skip to main content

provenant/output_schema/
resolved_package.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)]
16pub struct OutputResolvedPackage {
17    #[serde(rename = "type")]
18    pub package_type: OutputPackageType,
19    pub namespace: String,
20    pub name: String,
21    pub version: 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::ResolvedPackage> for OutputResolvedPackage {
74    fn from(value: &crate::models::ResolvedPackage) -> Self {
75        Self {
76            package_type: OutputPackageType::from(value.package_type),
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<&OutputResolvedPackage> for crate::models::ResolvedPackage {
139    type Error = String;
140    fn try_from(value: &OutputResolvedPackage) -> 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: crate::models::PackageType::try_from(&value.package_type)?,
163            namespace: value.namespace.clone(),
164            name: value.name.clone(),
165            version: value.version.clone(),
166            qualifiers: value.qualifiers.clone(),
167            subpath: value.subpath.clone(),
168            primary_language: value.primary_language.clone(),
169            description: value.description.clone(),
170            release_date: value.release_date.clone(),
171            parties,
172            keywords: value.keywords.clone(),
173            homepage_url: value.homepage_url.clone(),
174            download_url: value.download_url.clone(),
175            size: value.size,
176            sha1: value
177                .sha1
178                .as_ref()
179                .map(|s| crate::models::Sha1Digest::from_hex(s))
180                .transpose()
181                .map_err(|e| format!("invalid sha1: {}", e))?,
182            md5: value
183                .md5
184                .as_ref()
185                .map(|s| crate::models::Md5Digest::from_hex(s))
186                .transpose()
187                .map_err(|e| format!("invalid md5: {}", e))?,
188            sha256: value
189                .sha256
190                .as_ref()
191                .map(|s| crate::models::Sha256Digest::from_hex(s))
192                .transpose()
193                .map_err(|e| format!("invalid sha256: {}", e))?,
194            sha512: value
195                .sha512
196                .as_ref()
197                .map(|s| crate::models::Sha512Digest::from_hex(s))
198                .transpose()
199                .map_err(|e| format!("invalid sha512: {}", e))?,
200            bug_tracking_url: value.bug_tracking_url.clone(),
201            code_view_url: value.code_view_url.clone(),
202            vcs_url: value.vcs_url.clone(),
203            copyright: value.copyright.clone(),
204            holder: value.holder.clone(),
205            declared_license_expression: value.declared_license_expression.clone(),
206            declared_license_expression_spdx: value.declared_license_expression_spdx.clone(),
207            license_detections,
208            other_license_expression: value.other_license_expression.clone(),
209            other_license_expression_spdx: value.other_license_expression_spdx.clone(),
210            other_license_detections,
211            extracted_license_statement: value.extracted_license_statement.clone(),
212            notice_text: value.notice_text.clone(),
213            source_packages: value.source_packages.clone(),
214            file_references,
215            is_private: value.is_private,
216            is_virtual: value.is_virtual,
217            extra_data: value.extra_data.clone(),
218            dependencies,
219            repository_homepage_url: value.repository_homepage_url.clone(),
220            repository_download_url: value.repository_download_url.clone(),
221            api_data_url: value.api_data_url.clone(),
222            datasource_id: value
223                .datasource_id
224                .as_ref()
225                .map(crate::models::DatasourceId::try_from)
226                .transpose()?,
227            purl: value.purl.clone(),
228        })
229    }
230}