use std::path::PathBuf;
use crate::volatility::Volatility;
use super::dimensions::{Distance, IntegrationStrength, Visibility};
#[derive(Debug, Clone, Default)]
pub struct CouplingLocation {
pub file_path: Option<PathBuf>,
pub line: usize,
}
#[derive(Debug, Clone)]
pub struct CouplingMetrics {
pub source: String,
pub target: String,
pub strength: IntegrationStrength,
pub distance: Distance,
pub volatility: Volatility,
pub source_crate: Option<String>,
pub target_crate: Option<String>,
pub target_visibility: Visibility,
pub location: CouplingLocation,
}
impl CouplingMetrics {
pub fn new(
source: String,
target: String,
strength: IntegrationStrength,
distance: Distance,
volatility: Volatility,
) -> Self {
Self {
source,
target,
strength,
distance,
volatility,
source_crate: None,
target_crate: None,
target_visibility: Visibility::default(),
location: CouplingLocation::default(),
}
}
pub fn with_visibility(
source: String,
target: String,
strength: IntegrationStrength,
distance: Distance,
volatility: Volatility,
visibility: Visibility,
) -> Self {
Self {
source,
target,
strength,
distance,
volatility,
source_crate: None,
target_crate: None,
target_visibility: visibility,
location: CouplingLocation::default(),
}
}
#[allow(clippy::too_many_arguments)]
pub fn with_location(
source: String,
target: String,
strength: IntegrationStrength,
distance: Distance,
volatility: Volatility,
visibility: Visibility,
file_path: PathBuf,
line: usize,
) -> Self {
Self {
source,
target,
strength,
distance,
volatility,
source_crate: None,
target_crate: None,
target_visibility: visibility,
location: CouplingLocation {
file_path: Some(file_path),
line,
},
}
}
pub fn is_visibility_intrusive(&self) -> bool {
let same_crate = self.source_crate == self.target_crate;
let same_module =
self.distance == Distance::SameModule || self.distance == Distance::SameFunction;
self.target_visibility
.is_intrusive_from(same_crate, same_module)
}
pub fn effective_strength(&self) -> IntegrationStrength {
if self.is_visibility_intrusive() && self.strength != IntegrationStrength::Intrusive {
match self.strength {
IntegrationStrength::Contract => IntegrationStrength::Model,
IntegrationStrength::Model => IntegrationStrength::Functional,
IntegrationStrength::Functional => IntegrationStrength::Intrusive,
IntegrationStrength::Intrusive => IntegrationStrength::Intrusive,
}
} else {
self.strength
}
}
pub fn effective_strength_value(&self) -> f64 {
self.effective_strength().value()
}
pub fn strength_value(&self) -> f64 {
self.strength.value()
}
pub fn distance_value(&self) -> f64 {
self.distance.value()
}
pub fn volatility_value(&self) -> f64 {
self.volatility.value()
}
}