use std::convert::{TryFrom, TryInto};
use packageurl::PackageUrl;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr};
use url::Url;
pub(crate) type AcknowledgmentsT = Vec<Acknowledgment>;
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Acknowledgment {
pub names: Option<Vec<String>>,
pub organization: Option<String>,
pub summary: Option<String>,
pub urls: Option<Vec<Url>>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BranchesT(pub Vec<Branch>);
impl BranchesT {
pub(crate) fn product_ids(&self) -> Option<Vec<ProductIdT>> {
if self.0.is_empty() {
None
} else {
Some(self.0.iter().map(|x| x.try_into().unwrap()).collect())
}
}
}
impl TryFrom<&Branch> for ProductIdT {
type Error = &'static str;
fn try_from(b: &Branch) -> Result<Self, Self::Error> {
match &b.product {
Some(p) => Ok(p.product_id.clone()),
None => Err("Cannot convert Branch that does not contain a product to a ProductIdT"),
}
}
}
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Branch {
pub name: String,
pub category: BranchCategory,
pub product: Option<FullProductName>,
pub branches: Option<BranchesT>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub enum BranchCategory {
Architecture,
HostName,
Language,
Legacy,
PatchLevel,
ProductFamily,
ProductName,
ProductVersion,
ProductVersionRange,
ServicePack,
Specification,
Vendor,
}
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct FullProductName {
pub name: String,
pub product_id: ProductIdT,
pub product_identification_helper: Option<ProductIdentificationHelper>,
}
#[serde_as]
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ProductIdentificationHelper {
#[serde_as(as = "Option<DisplayFromStr>")]
pub cpe: Option<cpe::uri::OwnedUri>,
pub hashes: Option<Vec<HashCollection>>,
pub model_numbers: Option<Vec<String>>, #[serde_as(as = "Option<DisplayFromStr>")]
pub purl: Option<PackageUrl<'static>>,
pub sbom_urls: Option<Vec<Url>>,
pub serial_numbers: Option<Vec<String>>, pub skus: Option<Vec<String>>,
pub x_generic_uris: Option<Vec<Url>>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct HashCollection {
pub file_hashes: Vec<HashValue>,
pub file_name: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct HashValue {
pub algorithm: String,
pub value: String,
}
pub(crate) type LangT = String;
pub(crate) type NotesT = Vec<Note>;
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Note {
pub category: NoteCategory,
pub text: String,
pub audience: Option<String>,
pub title: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub enum NoteCategory {
Description,
Details,
Faq,
General,
LegalDisclaimer,
Other,
Summary,
}
pub(crate) type ProductGroupIdT = String;
pub(crate) type ProductGroupsT = Vec<ProductGroupIdT>;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ProductIdT(pub String);
pub(crate) type ProductsT = Vec<ProductIdT>;
pub(crate) type ReferencesT = Vec<Reference>;
#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Reference {
pub url: Url,
pub summary: String,
pub category: Option<ReferenceCategory>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub enum ReferenceCategory {
External,
#[serde(rename = "self")]
RefSelf,
}
pub(crate) type VersionT = String;