1use crate::AdvisoryType;
2use chrono::{DateTime, Utc};
3use clap::ValueEnum;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize)]
7pub struct TargetWithAdvisory {
8 pub name: Option<String>,
9 pub version: String,
10 pub ecosystem: Option<String>,
11 pub advisory_type: AdvisoryType,
12 pub repository_path: Option<String>,
13 pub advisories: Vec<Advisory>,
14}
15
16#[derive(Debug, Clone, Serialize)]
17pub struct Advisory {
18 pub ghsa_id: String,
19 pub cve_id: Option<String>,
20 pub summary: String,
21 pub description: String,
22 pub severity: Severity,
23 pub cvss_severities: CvssSeverities,
24 pub epss: Option<Epss>,
25 pub html_url: String,
26 pub published_at: DateTime<Utc>,
27 pub updated_at: DateTime<Utc>,
28 pub withdrawn_at: Option<DateTime<Utc>>,
29 pub vulnerabilities: Vec<Vulnerability>,
30}
31
32#[derive(
33 Debug,
34 Clone,
35 Copy,
36 PartialEq,
37 Eq,
38 PartialOrd,
39 Ord,
40 Hash,
41 Serialize,
42 Deserialize,
43 ValueEnum,
44 strum_macros::Display,
45)]
46#[serde(rename_all = "snake_case")]
47pub enum Severity {
48 Unknown,
49 Low,
50 Medium,
51 High,
52 Critical,
53}
54
55impl Severity {
56 pub const fn order(self) -> i32 {
58 match self {
59 Severity::Critical => 1,
60 Severity::High => 2,
61 Severity::Medium => 3,
62 Severity::Low => 4,
63 Severity::Unknown => 5,
64 }
65 }
66}
67
68#[derive(Debug, Clone, Serialize)]
69pub struct Vulnerability {
70 pub package: Package,
71 pub vulnerable_version_range: String,
72 pub patched_versions: Vec<String>,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
76pub struct Package {
77 pub ecosystem: String,
78 pub name: String,
79}
80
81#[derive(Debug, Clone, Serialize)]
82pub struct CvssSeverities {
83 pub cvss_v3: CvssScore,
84 pub cvss_v4: CvssScore,
85}
86
87#[derive(Debug, Clone, Serialize)]
88pub struct CvssScore {
89 pub vector_string: Option<String>,
90 pub score: Option<f64>,
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
94pub struct Epss {
95 pub percentage: f64,
96 pub percentile: f64,
97}