Skip to content

Commit

Permalink
Merge pull request #725 from Shnatsel/fix-api
Browse files Browse the repository at this point in the history
Fix API requiring non-exhaustive matching that led to bugs
  • Loading branch information
Shnatsel authored Jun 4, 2024
2 parents 11a4051 + 21cf409 commit 44ddc74
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 15 deletions.
18 changes: 4 additions & 14 deletions cargo-cyclonedx/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,22 +729,12 @@ impl GeneratedSbom {
let mut writer = BufWriter::new(file);
match config.format() {
Format::Json => {
match spec_version {
V1_3 => bom.output_as_json_v1_3(&mut writer),
V1_4 => bom.output_as_json_v1_4(&mut writer),
V1_5 => bom.output_as_json_v1_5(&mut writer),
_ => unimplemented!(),
}
.map_err(SbomWriterError::JsonWriteError)?;
bom.output_as_json(&mut writer, spec_version)
.map_err(SbomWriterError::JsonWriteError)?;
}
Format::Xml => {
match spec_version {
V1_3 => bom.output_as_xml_v1_3(&mut writer),
V1_4 => bom.output_as_xml_v1_4(&mut writer),
V1_5 => bom.output_as_xml_v1_5(&mut writer),
_ => unimplemented!(),
}
.map_err(SbomWriterError::XmlWriteError)?;
bom.output_as_xml(&mut writer, spec_version)
.map_err(SbomWriterError::XmlWriteError)?;
}
}

Expand Down
1 change: 0 additions & 1 deletion cyclonedx-bom/src/external_models/uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

use std::{convert::TryFrom, str::FromStr};

use crate::prelude::DateTime;
use fluent_uri::Uri as Url;
use packageurl::PackageUrl;
use thiserror::Error;
Expand Down
62 changes: 62 additions & 0 deletions cyclonedx-bom/src/models/bom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,68 @@ impl Bom {
}
}

/// Parse the input as a JSON document conforming to the version of the specification that you provide.
/// Use [`parse_from_json`](Self::parse_from_json) if you want to support multiple versions instead.
pub fn parse_from_json_with_version<R: std::io::Read>(
reader: R,
version: SpecVersion,
) -> Result<Self, crate::errors::JsonReadError> {
// While the SpecVersion enum is non-exhaustive in the public API
// (and it probably shouldn't be!), we can match exhaustively here
// which avoids issues which crop up when the API user has to match:
// https://github.com/CycloneDX/cyclonedx-rust-cargo/pull/722
// https://github.com/CycloneDX/cyclonedx-rust-cargo/pull/723
match version {
SpecVersion::V1_3 => Self::parse_from_json_v1_3(reader),
SpecVersion::V1_4 => Self::parse_from_json_v1_4(reader),
SpecVersion::V1_5 => Self::parse_from_json_v1_5(reader),
}
}

/// Output as a JSON document conforming to the specification version that you provide.
pub fn output_as_json<W: std::io::Write>(
self,
writer: &mut W,
version: SpecVersion,
) -> Result<(), crate::errors::JsonWriteError> {
// See `parse_from_json_with_version` for an explanation
// why we do this match here and why API users shouldn't do it
match version {
SpecVersion::V1_3 => self.output_as_json_v1_3(writer),
SpecVersion::V1_4 => self.output_as_json_v1_4(writer),
SpecVersion::V1_5 => self.output_as_json_v1_5(writer),
}
}

/// Parse the input as an XML document conforming to the version of the specification that you provide.
pub fn parse_from_xml_with_version<R: std::io::Read>(
reader: R,
version: SpecVersion,
) -> Result<Self, crate::errors::XmlReadError> {
// See `parse_from_json_with_version` for an explanation
// why we do this match here and why API users shouldn't do it
match version {
SpecVersion::V1_3 => Self::parse_from_xml_v1_3(reader),
SpecVersion::V1_4 => Self::parse_from_xml_v1_4(reader),
SpecVersion::V1_5 => Self::parse_from_xml_v1_5(reader),
}
}

/// Output as an XML document conforming to the specification version that you provide.
pub fn output_as_xml<W: std::io::Write>(
self,
writer: &mut W,
version: SpecVersion,
) -> Result<(), crate::errors::XmlWriteError> {
// See `parse_from_json_with_version` for an explanation
// why we do this match here and why API users shouldn't do it
match version {
SpecVersion::V1_3 => self.output_as_xml_v1_3(writer),
SpecVersion::V1_4 => self.output_as_xml_v1_4(writer),
SpecVersion::V1_5 => self.output_as_xml_v1_5(writer),
}
}

/// Parse the input as a JSON document conforming to [version 1.3 of the specification](https://cyclonedx.org/docs/1.3/json/)
pub fn parse_from_json_v1_3<R: std::io::Read>(
mut reader: R,
Expand Down

0 comments on commit 44ddc74

Please sign in to comment.