cyclonedx_bom/models/
component_data.rs

1/*
2 * This file is part of CycloneDX Rust Cargo.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 */
18
19use 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/// Inline Component Data
32#[derive(Clone, Debug, PartialEq, Eq, Hash)]
33pub struct ComponentData {
34    pub bom_ref: Option<BomReference>,
35    /// 'type' field
36    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/// Type of data
65#[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/// bom-1.5.schema.json #definitions/graphicsCollection
102#[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/// bom-1.5.schema.json #definitions/graphic
119#[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}