cyclonedx_bom/models/
component_data.rs1use crate::{
20 external_models::uri::validate_uri,
21 models::{attachment::Attachment, data_governance::DataGovernance},
22 prelude::{Uri, Validate, ValidationResult},
23 validation::{ValidationContext, ValidationError},
24};
25
26use super::{
27 bom::{BomReference, SpecVersion},
28 property::Properties,
29};
30
31#[derive(Clone, Debug, PartialEq, Eq, Hash)]
33pub struct ComponentData {
34 pub bom_ref: Option<BomReference>,
35 pub data_type: ComponentDataType,
37 pub name: Option<String>,
38 pub contents: Option<DataContents>,
39 pub classification: Option<String>,
40 pub sensitive_data: Option<String>,
41 pub graphics: Option<GraphicsCollection>,
42 pub description: Option<String>,
43 pub governance: Option<DataGovernance>,
44}
45
46impl Validate for ComponentData {
47 fn validate_version(&self, version: SpecVersion) -> ValidationResult {
48 ValidationContext::new()
49 .add_field("type", &self.data_type, validate_datatype)
50 .add_struct_option("contents", self.contents.as_ref(), version)
51 .add_struct_option("graphics", self.graphics.as_ref(), version)
52 .add_struct_option("governance", self.governance.as_ref(), version)
53 .into()
54 }
55}
56
57fn validate_datatype(datatype: &ComponentDataType) -> Result<(), ValidationError> {
58 if matches!(datatype, ComponentDataType::Unknown(_)) {
59 return Err("Unknown component data type found".into());
60 }
61 Ok(())
62}
63
64#[derive(Clone, Debug, PartialEq, Eq, strum::Display, strum::EnumString, Hash)]
66#[strum(serialize_all = "kebab-case")]
67pub enum ComponentDataType {
68 SourceCode,
69 Configuration,
70 Dataset,
71 Definition,
72 Other,
73 #[doc(hidden)]
74 #[strum(default)]
75 Unknown(String),
76}
77
78impl From<String> for ComponentDataType {
79 fn from(value: String) -> Self {
80 std::str::FromStr::from_str(&value).expect("infallible")
81 }
82}
83
84#[derive(Clone, Debug, PartialEq, Eq, Hash)]
85pub struct DataContents {
86 pub attachment: Option<Attachment>,
87 pub url: Option<Uri>,
88 pub properties: Option<Properties>,
89}
90
91impl Validate for DataContents {
92 fn validate_version(&self, version: SpecVersion) -> ValidationResult {
93 ValidationContext::new()
94 .add_struct_option("attachment", self.attachment.as_ref(), version)
95 .add_field_option("url", self.url.as_ref(), validate_uri)
96 .add_struct_option("properties", self.properties.as_ref(), version)
97 .into()
98 }
99}
100
101#[derive(Clone, Debug, PartialEq, Eq, Hash)]
103pub struct GraphicsCollection {
104 pub description: Option<String>,
105 pub collection: Option<Vec<Graphic>>,
106}
107
108impl Validate for GraphicsCollection {
109 fn validate_version(&self, version: SpecVersion) -> ValidationResult {
110 ValidationContext::new()
111 .add_list_option("collection", self.collection.as_ref(), |graphic| {
112 graphic.validate_version(version)
113 })
114 .into()
115 }
116}
117
118#[derive(Clone, Debug, PartialEq, Eq, Hash)]
120pub struct Graphic {
121 pub name: Option<String>,
122 pub image: Option<Attachment>,
123}
124
125impl Validate for Graphic {
126 fn validate_version(&self, version: SpecVersion) -> ValidationResult {
127 ValidationContext::new()
128 .add_struct_option("image", self.image.as_ref(), version)
129 .into()
130 }
131}