Skip to content

Commit 9a0f1a7

Browse files
authored
Merge pull request #585 from justahero/sebastian/feat/general-parse-function
Add function to parse JSON without version
2 parents c29ef5c + 4ac4f5d commit 9a0f1a7

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

cyclonedx-bom/src/errors.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ pub enum XmlWriteError {
6868
#[derive(Debug, thiserror::Error)]
6969
#[non_exhaustive]
7070
pub enum JsonReadError {
71-
#[error("IO Error #{0}")]
72-
IoError(#[from] std::io::Error),
73-
7471
#[error("Failed to deserialize JSON: {error}")]
7572
JsonElementReadError {
7673
#[from]

cyclonedx-bom/src/models/bom.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,29 @@ pub struct Bom {
8989
}
9090

9191
impl Bom {
92+
/// General function to parse a JSON file, fetches the `specVersion` field first then applies the right conversion.
93+
pub fn parse_from_json<R: std::io::Read>(
94+
mut reader: R,
95+
) -> Result<Self, crate::errors::JsonReadError> {
96+
let json: serde_json::Value = serde_json::from_reader(&mut reader)?;
97+
98+
if let Some(version) = json.get("specVersion") {
99+
let version = version
100+
.as_str()
101+
.ok_or_else(|| BomError::UnsupportedSpecVersion(version.to_string()))?;
102+
103+
match SpecVersion::from_str(version)? {
104+
SpecVersion::V1_3 => Ok(crate::specs::v1_3::bom::Bom::deserialize(json)?.into()),
105+
SpecVersion::V1_4 => Ok(crate::specs::v1_4::bom::Bom::deserialize(json)?.into()),
106+
}
107+
} else {
108+
return Err(BomError::UnsupportedSpecVersion(
109+
"No field 'specVersion' found".to_string(),
110+
)
111+
.into());
112+
}
113+
}
114+
92115
/// Parse the input as a JSON document conforming to [version 1.3 of the specification](https://cyclonedx.org/docs/1.3/json/)
93116
pub fn parse_from_json_v1_3<R: std::io::Read>(
94117
mut reader: R,
@@ -568,6 +591,19 @@ mod test {
568591
use super::*;
569592
use pretty_assertions::assert_eq;
570593

594+
#[test]
595+
fn it_should_parse_json_using_function_without_suffix() {
596+
let input = r#"{
597+
"bomFormat": "CycloneDX",
598+
"specVersion": "1.3",
599+
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
600+
"version": 1,
601+
"components": []
602+
}"#;
603+
let result = Bom::parse_from_json(input.as_bytes());
604+
assert!(result.is_ok());
605+
}
606+
571607
#[test]
572608
fn it_should_validate_an_empty_bom_as_passed() {
573609
let bom = Bom {

0 commit comments

Comments
 (0)