Skip to main content

provenant/output_schema/
top_level_dependency.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::resolved_package::OutputResolvedPackage;
9use super::serde_helpers::serialize_optional_map_as_object;
10
11#[derive(Serialize, Deserialize, Debug, Clone)]
12pub struct OutputTopLevelDependency {
13    pub purl: Option<String>,
14    pub extracted_requirement: Option<String>,
15    pub scope: Option<String>,
16    pub is_runtime: Option<bool>,
17    pub is_optional: Option<bool>,
18    pub is_pinned: Option<bool>,
19    pub is_direct: Option<bool>,
20    pub resolved_package: Option<Box<OutputResolvedPackage>>,
21    #[serde(default, serialize_with = "serialize_optional_map_as_object")]
22    pub extra_data: Option<HashMap<String, serde_json::Value>>,
23    pub dependency_uid: String,
24    pub for_package_uid: Option<String>,
25    pub datafile_path: String,
26    pub datasource_id: OutputDatasourceId,
27    pub namespace: Option<String>,
28}
29
30impl From<&crate::models::TopLevelDependency> for OutputTopLevelDependency {
31    fn from(value: &crate::models::TopLevelDependency) -> Self {
32        Self {
33            purl: value.purl.as_deref().map(crate::models::normalize_purl),
34            extracted_requirement: value.extracted_requirement.clone(),
35            scope: value.scope.clone(),
36            is_runtime: value.is_runtime,
37            is_optional: value.is_optional,
38            is_pinned: value.is_pinned,
39            is_direct: value.is_direct,
40            resolved_package: value
41                .resolved_package
42                .as_ref()
43                .map(|rp| Box::new(OutputResolvedPackage::from(rp.as_ref()))),
44            extra_data: value.extra_data.clone(),
45            dependency_uid: value.dependency_uid.to_string(),
46            for_package_uid: value.for_package_uid.as_ref().map(|uid| uid.to_string()),
47            datafile_path: value.datafile_path.clone(),
48            datasource_id: OutputDatasourceId::from(value.datasource_id),
49            namespace: value.namespace.clone(),
50        }
51    }
52}
53
54impl TryFrom<&OutputTopLevelDependency> for crate::models::TopLevelDependency {
55    type Error = String;
56    fn try_from(value: &OutputTopLevelDependency) -> Result<Self, Self::Error> {
57        let resolved_package = value
58            .resolved_package
59            .as_ref()
60            .map(|rp| crate::models::ResolvedPackage::try_from(rp.as_ref()).map(Box::new))
61            .transpose()?;
62        Ok(Self {
63            purl: value.purl.clone(),
64            extracted_requirement: value.extracted_requirement.clone(),
65            scope: value.scope.clone(),
66            is_runtime: value.is_runtime,
67            is_optional: value.is_optional,
68            is_pinned: value.is_pinned,
69            is_direct: value.is_direct,
70            resolved_package,
71            extra_data: value.extra_data.clone(),
72            dependency_uid: crate::models::DependencyUid::from_raw(value.dependency_uid.clone()),
73            for_package_uid: value
74                .for_package_uid
75                .as_ref()
76                .map(|s| crate::models::PackageUid::from_raw(s.clone())),
77            datafile_path: value.datafile_path.clone(),
78            datasource_id: crate::models::DatasourceId::try_from(&value.datasource_id)
79                .map_err(|e| format!("invalid datasource_id: {}", e))?,
80            namespace: value.namespace.clone(),
81        })
82    }
83}