use serde::de::{Error, MapAccess, Visitor};
use serde::{Deserialize, Deserializer, Serialize};
use serde_with::skip_serializing_none;
use std::fmt::{self, Formatter};
#[non_exhaustive]
#[skip_serializing_none]
#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct VulnerabilityRisks {
#[serde(rename = "epss")]
pub epss: Option<crate::datadogV2::model::EPSS>,
#[serde(rename = "exploit_available")]
pub exploit_available: bool,
#[serde(rename = "exploit_sources")]
pub exploit_sources: Vec<String>,
#[serde(rename = "exploitation_probability")]
pub exploitation_probability: bool,
#[serde(rename = "poc_exploit_available")]
pub poc_exploit_available: bool,
#[serde(flatten)]
pub additional_properties: std::collections::BTreeMap<String, serde_json::Value>,
#[serde(skip)]
#[serde(default)]
pub(crate) _unparsed: bool,
}
impl VulnerabilityRisks {
pub fn new(
exploit_available: bool,
exploit_sources: Vec<String>,
exploitation_probability: bool,
poc_exploit_available: bool,
) -> VulnerabilityRisks {
VulnerabilityRisks {
epss: None,
exploit_available,
exploit_sources,
exploitation_probability,
poc_exploit_available,
additional_properties: std::collections::BTreeMap::new(),
_unparsed: false,
}
}
pub fn epss(mut self, value: crate::datadogV2::model::EPSS) -> Self {
self.epss = Some(value);
self
}
pub fn additional_properties(
mut self,
value: std::collections::BTreeMap<String, serde_json::Value>,
) -> Self {
self.additional_properties = value;
self
}
}
impl<'de> Deserialize<'de> for VulnerabilityRisks {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct VulnerabilityRisksVisitor;
impl<'a> Visitor<'a> for VulnerabilityRisksVisitor {
type Value = VulnerabilityRisks;
fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_str("a mapping")
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'a>,
{
let mut epss: Option<crate::datadogV2::model::EPSS> = None;
let mut exploit_available: Option<bool> = None;
let mut exploit_sources: Option<Vec<String>> = None;
let mut exploitation_probability: Option<bool> = None;
let mut poc_exploit_available: Option<bool> = None;
let mut additional_properties: std::collections::BTreeMap<
String,
serde_json::Value,
> = std::collections::BTreeMap::new();
let mut _unparsed = false;
while let Some((k, v)) = map.next_entry::<String, serde_json::Value>()? {
match k.as_str() {
"epss" => {
if v.is_null() {
continue;
}
epss = Some(serde_json::from_value(v).map_err(M::Error::custom)?);
}
"exploit_available" => {
exploit_available =
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
}
"exploit_sources" => {
exploit_sources =
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
}
"exploitation_probability" => {
exploitation_probability =
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
}
"poc_exploit_available" => {
poc_exploit_available =
Some(serde_json::from_value(v).map_err(M::Error::custom)?);
}
&_ => {
if let Ok(value) = serde_json::from_value(v.clone()) {
additional_properties.insert(k, value);
}
}
}
}
let exploit_available = exploit_available
.ok_or_else(|| M::Error::missing_field("exploit_available"))?;
let exploit_sources =
exploit_sources.ok_or_else(|| M::Error::missing_field("exploit_sources"))?;
let exploitation_probability = exploitation_probability
.ok_or_else(|| M::Error::missing_field("exploitation_probability"))?;
let poc_exploit_available = poc_exploit_available
.ok_or_else(|| M::Error::missing_field("poc_exploit_available"))?;
let content = VulnerabilityRisks {
epss,
exploit_available,
exploit_sources,
exploitation_probability,
poc_exploit_available,
additional_properties,
_unparsed,
};
Ok(content)
}
}
deserializer.deserialize_any(VulnerabilityRisksVisitor)
}
}