1use crate::{
5 advisory::{self, Advisory, affected::FunctionPath},
6 package::Package,
7};
8use serde::{Deserialize, Serialize};
9
10#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
12pub struct Vulnerability {
13 pub advisory: advisory::Metadata,
15
16 pub versions: advisory::Versions,
18
19 pub affected: Option<advisory::Affected>,
21
22 pub package: Package,
24}
25
26impl Vulnerability {
27 pub fn new(advisory: &Advisory, package: &Package) -> Self {
29 Self {
30 advisory: advisory.metadata.clone(),
31 versions: advisory.versions.clone(),
32 affected: advisory.affected.clone(),
33 package: package.clone(),
34 }
35 }
36
37 pub fn affected_functions(&self) -> Option<Vec<FunctionPath>> {
39 self.affected.as_ref().and_then(|affected| {
40 if affected.functions.is_empty() {
41 None
42 } else {
43 let mut result = vec![];
44 for (path, versions) in &affected.functions {
45 if versions
46 .iter()
47 .any(|req| req.matches(&self.package.version.clone()))
48 {
49 result.push(path.clone());
50 }
51 }
52 Some(result)
53 }
54 })
55 }
56}