Skip to content

Commit 5a15088

Browse files
committed
Add SpecVersion enum type to set supported versions
This adds a `SpecVersion` enum type to encode supported versions, currently 1.3 and 1.4. Signed-off-by: Sebastian Ziebell <[email protected]>
1 parent 1a377ce commit 5a15088

File tree

4 files changed

+59
-12
lines changed

4 files changed

+59
-12
lines changed

cyclonedx-bom/src/errors.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ pub enum BomError {
2727

2828
#[error("Failed to serialize BOM to v1.3: {0}")]
2929
BomV13SerializationError(String),
30+
31+
#[error("Unsupported Spec Version '{0}'")]
32+
UnsupportedSpecVersion(String),
3033
}
3134

3235
#[derive(Debug, thiserror::Error)]
@@ -63,11 +66,19 @@ pub enum XmlWriteError {
6366
#[derive(Debug, thiserror::Error)]
6467
#[non_exhaustive]
6568
pub enum JsonReadError {
69+
#[error("IO Error #{0}")]
70+
IoError(#[from] std::io::Error),
71+
6672
#[error("Failed to deserialize JSON: {error}")]
6773
JsonElementReadError {
6874
#[from]
6975
error: serde_json::Error,
7076
},
77+
#[error("Invalid input format found: {error}")]
78+
BomError {
79+
#[from]
80+
error: BomError,
81+
},
7182
}
7283

7384
#[derive(Debug, thiserror::Error)]

cyclonedx-bom/src/models/bom.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
use std::collections::HashSet;
2020
use std::convert::TryInto;
2121
use std::fmt;
22+
use std::str::FromStr;
2223

2324
use once_cell::sync::Lazy;
2425
use regex::Regex;
26+
use serde::{Deserialize, Serialize};
2527
use serde_json::Value;
2628
use xml::{EmitterConfig, EventReader, EventWriter, ParserConfig};
2729

30+
use crate::errors::BomError;
2831
use crate::models::component::{Component, Components};
2932
use crate::models::composition::{BomReference, Compositions};
3033
use crate::models::dependency::Dependencies;
@@ -39,6 +42,38 @@ use crate::validation::{
3942
};
4043
use crate::xml::{FromXmlDocument, ToXml};
4144

45+
/// Represents the spec version of a BOM.
46+
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)]
47+
#[non_exhaustive]
48+
pub enum SpecVersion {
49+
#[serde(rename = "1.3")]
50+
V1_3,
51+
#[serde(rename = "1.4")]
52+
V1_4,
53+
}
54+
55+
impl FromStr for SpecVersion {
56+
type Err = BomError;
57+
58+
fn from_str(input: &str) -> Result<Self, Self::Err> {
59+
match input {
60+
"1.3" => Ok(SpecVersion::V1_3),
61+
"1.4" => Ok(SpecVersion::V1_4),
62+
s => Err(BomError::UnsupportedSpecVersion(s.to_string())),
63+
}
64+
}
65+
}
66+
67+
impl ToString for SpecVersion {
68+
fn to_string(&self) -> String {
69+
let s = match self {
70+
SpecVersion::V1_3 => "1.3",
71+
SpecVersion::V1_4 => "1.4",
72+
};
73+
s.to_string()
74+
}
75+
}
76+
4277
#[derive(Debug, PartialEq, Eq)]
4378
pub struct Bom {
4479
pub version: u32,

cyclonedx-bom/src/specs/v1_3/bom.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
use crate::errors::BomError;
20+
use crate::models::bom::SpecVersion;
2021
use crate::{
2122
models::{self},
2223
utilities::{convert_optional, try_convert_optional},
@@ -46,7 +47,7 @@ struct Vulnerabilities();
4647
#[serde(rename_all = "camelCase")]
4748
pub(crate) struct Bom {
4849
bom_format: BomFormat,
49-
spec_version: String,
50+
spec_version: SpecVersion,
5051
version: Option<u32>,
5152
serial_number: Option<UrnUuid>,
5253
#[serde(skip_serializing_if = "Option::is_none")]
@@ -72,7 +73,7 @@ impl From<models::bom::Bom> for Bom {
7273
fn from(other: models::bom::Bom) -> Self {
7374
Self {
7475
bom_format: BomFormat::CycloneDX,
75-
spec_version: "1.3".to_string(),
76+
spec_version: SpecVersion::V1_3,
7677
version: Some(other.version),
7778
serial_number: convert_optional(other.serial_number),
7879
metadata: convert_optional(other.metadata),
@@ -94,7 +95,7 @@ impl TryFrom<models::bom::Bom> for Bom {
9495
fn try_from(other: models::bom::Bom) -> Result<Self, Self::Error> {
9596
Ok(Self {
9697
bom_format: BomFormat::CycloneDX,
97-
spec_version: "1.3".to_string(),
98+
spec_version: SpecVersion::V1_3,
9899
version: Some(other.version),
99100
serial_number: convert_optional(other.serial_number),
100101
metadata: try_convert_optional(other.metadata)?,
@@ -329,7 +330,7 @@ impl FromXmlDocument for Bom {
329330
})?;
330331
Ok(Self {
331332
bom_format: BomFormat::CycloneDX,
332-
spec_version: "1.3".to_string(),
333+
spec_version: SpecVersion::V1_3,
333334
version,
334335
serial_number,
335336
metadata,
@@ -387,7 +388,7 @@ pub(crate) mod test {
387388
pub(crate) fn minimal_bom_example() -> Bom {
388389
Bom {
389390
bom_format: BomFormat::CycloneDX,
390-
spec_version: "1.3".to_string(),
391+
spec_version: SpecVersion::V1_3,
391392
version: Some(1),
392393
serial_number: Some(UrnUuid("fake-uuid".to_string())),
393394
metadata: None,
@@ -404,7 +405,7 @@ pub(crate) mod test {
404405
pub(crate) fn full_bom_example() -> Bom {
405406
Bom {
406407
bom_format: BomFormat::CycloneDX,
407-
spec_version: "1.3".to_string(),
408+
spec_version: SpecVersion::V1_3,
408409
version: Some(1),
409410
serial_number: Some(UrnUuid("fake-uuid".to_string())),
410411
metadata: Some(example_metadata()),

cyclonedx-bom/src/specs/v1_4/bom.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*/
1818

1919
use crate::{
20-
models::{self},
20+
models::{self, bom::SpecVersion},
2121
utilities::convert_optional,
2222
xml::{
2323
expected_namespace_or_error, optional_attribute, read_lax_validation_tag,
@@ -40,7 +40,7 @@ use xml::{reader, writer::XmlEvent};
4040
#[serde(rename_all = "camelCase")]
4141
pub(crate) struct Bom {
4242
bom_format: BomFormat,
43-
spec_version: String,
43+
spec_version: SpecVersion,
4444
version: Option<u32>,
4545
serial_number: Option<UrnUuid>,
4646
#[serde(skip_serializing_if = "Option::is_none")]
@@ -65,7 +65,7 @@ impl From<models::bom::Bom> for Bom {
6565
fn from(other: models::bom::Bom) -> Self {
6666
Self {
6767
bom_format: BomFormat::CycloneDX,
68-
spec_version: "1.4".to_string(),
68+
spec_version: SpecVersion::V1_4,
6969
version: Some(other.version),
7070
serial_number: convert_optional(other.serial_number),
7171
metadata: convert_optional(other.metadata),
@@ -316,7 +316,7 @@ impl FromXmlDocument for Bom {
316316
})?;
317317
Ok(Self {
318318
bom_format: BomFormat::CycloneDX,
319-
spec_version: "1.4".to_string(),
319+
spec_version: SpecVersion::V1_4,
320320
version,
321321
serial_number,
322322
metadata,
@@ -376,7 +376,7 @@ pub(crate) mod test {
376376
pub(crate) fn minimal_bom_example() -> Bom {
377377
Bom {
378378
bom_format: BomFormat::CycloneDX,
379-
spec_version: "1.4".to_string(),
379+
spec_version: SpecVersion::V1_4,
380380
version: Some(1),
381381
serial_number: Some(UrnUuid("fake-uuid".to_string())),
382382
metadata: None,
@@ -393,7 +393,7 @@ pub(crate) mod test {
393393
pub(crate) fn full_bom_example() -> Bom {
394394
Bom {
395395
bom_format: BomFormat::CycloneDX,
396-
spec_version: "1.4".to_string(),
396+
spec_version: SpecVersion::V1_4,
397397
version: Some(1),
398398
serial_number: Some(UrnUuid("fake-uuid".to_string())),
399399
metadata: Some(example_metadata()),

0 commit comments

Comments
 (0)