use libcnb_data::sbom::SbomFormat;
use std::fs;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct Sbom {
pub format: SbomFormat,
pub data: Vec<u8>,
}
impl Sbom {
pub fn from_path<P: AsRef<Path>>(format: SbomFormat, path: P) -> std::io::Result<Self> {
fs::read(path.as_ref()).map(|data| Self { format, data })
}
pub fn from_bytes<D: Into<Vec<u8>>>(format: SbomFormat, data: D) -> Self {
Self {
format,
data: data.into(),
}
}
}
#[cfg(feature = "cyclonedx-bom")]
impl TryFrom<cyclonedx_bom::models::bom::Bom> for Sbom {
type Error = cyclonedx_bom::errors::JsonWriteError;
fn try_from(cyclonedx_bom: cyclonedx_bom::models::bom::Bom) -> Result<Self, Self::Error> {
let mut data = Vec::new();
cyclonedx_bom.output_as_json_v1_3(&mut data)?;
Ok(Self {
format: SbomFormat::CycloneDxJson,
data,
})
}
}
pub(crate) fn cnb_sbom_path<P: AsRef<Path>>(
sbom_format: &SbomFormat,
base_directory: P,
base_name: &str,
) -> PathBuf {
let suffix = match sbom_format {
SbomFormat::CycloneDxJson => "cdx.json",
SbomFormat::SpdxJson => "spdx.json",
SbomFormat::SyftJson => "syft.json",
};
base_directory
.as_ref()
.join(format!("{base_name}.sbom.{suffix}"))
}