use crate::model::CanonicalId;
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone)]
pub struct DiffVertex {
pub left_pos: Option<CanonicalId>,
pub right_pos: Option<CanonicalId>,
pub processed_together: Vec<CanonicalId>,
}
impl DiffVertex {
#[must_use]
pub const fn new(left_pos: Option<CanonicalId>, right_pos: Option<CanonicalId>) -> Self {
Self {
left_pos,
right_pos,
processed_together: Vec::new(),
}
}
#[must_use]
pub const fn start() -> Self {
Self::new(None, None)
}
#[must_use]
pub fn is_end(&self) -> bool {
self.left_pos.is_none() && self.right_pos.is_none() && !self.processed_together.is_empty()
}
}
impl PartialEq for DiffVertex {
fn eq(&self, other: &Self) -> bool {
self.left_pos == other.left_pos && self.right_pos == other.right_pos
}
}
impl Eq for DiffVertex {}
impl Hash for DiffVertex {
fn hash<H: Hasher>(&self, state: &mut H) {
self.left_pos.hash(state);
self.right_pos.hash(state);
}
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum DiffEdge {
ComponentRemoved {
component_id: CanonicalId,
cost: u32,
},
ComponentAdded {
component_id: CanonicalId,
cost: u32,
},
VersionChanged {
component_id: CanonicalId,
old_version: String,
new_version: String,
cost: u32,
},
LicenseChanged {
component_id: CanonicalId,
cost: u32,
},
SupplierChanged {
component_id: CanonicalId,
cost: u32,
},
VulnerabilityIntroduced {
component_id: CanonicalId,
vuln_id: String,
cost: u32,
},
VulnerabilityResolved {
component_id: CanonicalId,
vuln_id: String,
reward: i32,
},
DependencyAdded {
from: CanonicalId,
to: CanonicalId,
cost: u32,
},
DependencyRemoved {
from: CanonicalId,
to: CanonicalId,
cost: u32,
},
ComponentUnchanged { component_id: CanonicalId },
}
#[allow(dead_code)]
impl DiffEdge {
pub const fn cost(&self) -> i32 {
match self {
Self::ComponentRemoved { cost, .. }
| Self::ComponentAdded { cost, .. }
| Self::VersionChanged { cost, .. }
| Self::LicenseChanged { cost, .. }
| Self::SupplierChanged { cost, .. }
| Self::VulnerabilityIntroduced { cost, .. }
| Self::DependencyAdded { cost, .. }
| Self::DependencyRemoved { cost, .. } => *cost as i32,
Self::VulnerabilityResolved { reward, .. } => *reward,
Self::ComponentUnchanged { .. } => 0,
}
}
pub const fn is_change(&self) -> bool {
!matches!(self, Self::ComponentUnchanged { .. })
}
}