cyclonedx_rust/
component.rs

1use derive_builder::Builder;
2use serde::{Deserialize, Serialize};
3use yaserde_derive::{YaDeserialize, YaSerialize};
4
5use classification::Classification;
6use external_reference::ExternalReference;
7use pedigree_type::PedigreeType;
8use scope::Scope;
9use swid::SwidType;
10
11use crate::common::hash_type::HashType;
12use crate::common::license::Licenses;
13use crate::common::organization::OrganizationalEntity;
14
15pub mod classification;
16pub mod external_reference;
17pub mod pedigree_type;
18pub mod scope;
19pub mod swid;
20
21#[derive(Clone, Builder, PartialEq, Debug, Serialize, Deserialize, YaSerialize, YaDeserialize)]
22#[yaserde(
23    prefix = "ns",
24    default_namespace = "ns",
25    namespace = "ns: http://cyclonedx.org/schema/bom/1.2"
26)]
27pub struct Component {
28    #[serde(rename = "type")]
29    #[yaserde(rename = "type", attribute)]
30    pub component_type: Classification,
31
32    #[serde(rename = "mime-type")]
33    #[yaserde(rename = "mime-type", attribute)]
34    pub mime_type: Option<String>,
35
36    #[serde(rename = "bom-ref")]
37    #[yaserde(rename = "bom-ref", attribute)]
38    pub bom_ref: Option<String>,
39
40    #[yaserde(prefix = "ns")]
41    pub supplier: Option<OrganizationalEntity>,
42    #[yaserde(prefix = "ns")]
43    pub author: Option<String>,
44    #[yaserde(prefix = "ns")]
45    pub publisher: Option<String>,
46    #[yaserde(prefix = "ns")]
47    pub group: Option<String>,
48    #[yaserde(prefix = "ns")]
49    pub name: Option<String>,
50    #[yaserde(prefix = "ns")]
51    pub version: Option<String>,
52    #[yaserde(prefix = "ns")]
53    pub description: Option<String>,
54    #[yaserde(prefix = "ns")]
55    pub scope: Option<Scope>,
56    #[yaserde(prefix = "ns")]
57    pub hashes: Vec<HashType>,
58    #[yaserde(prefix = "ns")]
59    pub licenses: Vec<Licenses>,
60    #[yaserde(prefix = "ns")]
61    pub copyright: Option<String>,
62    #[yaserde(prefix = "ns")]
63    pub purl: Option<String>,
64    #[yaserde(prefix = "ns")]
65    pub swid: Option<SwidType>,
66    #[yaserde(prefix = "ns")]
67    pub modified: Option<bool>,
68    pub pedigree: Option<PedigreeType>,
69    pub external_references: Vec<ExternalReference>,
70    pub components: Vec<Component>,
71}
72
73#[cfg(test)]
74pub mod tests {
75    use super::*;
76    use crate::common::attached_text::BomEncoding;
77    use std::fs::File;
78    use std::io::BufReader;
79    use std::path::PathBuf;
80    use yaserde::de;
81
82    #[test]
83    pub fn can_decode() {
84        let reader = setup("component-1.2.xml");
85
86        let component: Component = de::from_reader(reader).unwrap();
87
88        assert_eq!(component.name.unwrap(), "Acme Application");
89        assert_eq!(component.version.unwrap(), "9.1.1");
90        let swid = component.swid.unwrap();
91        assert_eq!(
92            swid.tag_id,
93            "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1"
94        );
95        assert_eq!(swid.name, "Acme Application");
96        assert_eq!(swid.version.unwrap(), "9.1.1");
97        let text_type = swid.text.unwrap();
98        assert_eq!(text_type.content_type.unwrap(), "text/xml");
99        assert_eq!(text_type.encoding.unwrap(), BomEncoding::Base64);
100        assert_eq!(text_type.value, "text value");
101    }
102
103    fn setup(file: &str) -> BufReader<File> {
104        let mut test_folder = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
105        test_folder.push("resources/test/".to_owned() + file);
106        let file = File::open(test_folder);
107        let reader = BufReader::new(file.unwrap());
108        reader
109    }
110}