provenant/output_schema/
top_level_dependency.rs1use 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}