cargo_coupling/metrics/
coupling.rs1use std::path::PathBuf;
2
3use crate::volatility::Volatility;
4
5use super::dimensions::{Distance, IntegrationStrength, Visibility};
6
7#[derive(Debug, Clone, Default)]
8pub struct CouplingLocation {
9 pub file_path: Option<PathBuf>,
11 pub line: usize,
13}
14
15#[derive(Debug, Clone)]
17pub struct CouplingMetrics {
18 pub source: String,
20 pub target: String,
22 pub strength: IntegrationStrength,
24 pub distance: Distance,
26 pub volatility: Volatility,
28 pub source_crate: Option<String>,
30 pub target_crate: Option<String>,
32 pub target_visibility: Visibility,
34 pub location: CouplingLocation,
36}
37
38impl CouplingMetrics {
39 pub fn new(
41 source: String,
42 target: String,
43 strength: IntegrationStrength,
44 distance: Distance,
45 volatility: Volatility,
46 ) -> Self {
47 Self {
48 source,
49 target,
50 strength,
51 distance,
52 volatility,
53 source_crate: None,
54 target_crate: None,
55 target_visibility: Visibility::default(),
56 location: CouplingLocation::default(),
57 }
58 }
59
60 pub fn with_visibility(
62 source: String,
63 target: String,
64 strength: IntegrationStrength,
65 distance: Distance,
66 volatility: Volatility,
67 visibility: Visibility,
68 ) -> Self {
69 Self {
70 source,
71 target,
72 strength,
73 distance,
74 volatility,
75 source_crate: None,
76 target_crate: None,
77 target_visibility: visibility,
78 location: CouplingLocation::default(),
79 }
80 }
81
82 #[allow(clippy::too_many_arguments)]
84 pub fn with_location(
85 source: String,
86 target: String,
87 strength: IntegrationStrength,
88 distance: Distance,
89 volatility: Volatility,
90 visibility: Visibility,
91 file_path: PathBuf,
92 line: usize,
93 ) -> Self {
94 Self {
95 source,
96 target,
97 strength,
98 distance,
99 volatility,
100 source_crate: None,
101 target_crate: None,
102 target_visibility: visibility,
103 location: CouplingLocation {
104 file_path: Some(file_path),
105 line,
106 },
107 }
108 }
109
110 pub fn is_visibility_intrusive(&self) -> bool {
115 let same_crate = self.source_crate == self.target_crate;
116 let same_module =
117 self.distance == Distance::SameModule || self.distance == Distance::SameFunction;
118 self.target_visibility
119 .is_intrusive_from(same_crate, same_module)
120 }
121
122 pub fn effective_strength(&self) -> IntegrationStrength {
127 if self.is_visibility_intrusive() && self.strength != IntegrationStrength::Intrusive {
128 match self.strength {
130 IntegrationStrength::Contract => IntegrationStrength::Model,
131 IntegrationStrength::Model => IntegrationStrength::Functional,
132 IntegrationStrength::Functional => IntegrationStrength::Intrusive,
133 IntegrationStrength::Intrusive => IntegrationStrength::Intrusive,
134 }
135 } else {
136 self.strength
137 }
138 }
139
140 pub fn effective_strength_value(&self) -> f64 {
142 self.effective_strength().value()
143 }
144
145 pub fn strength_value(&self) -> f64 {
147 self.strength.value()
148 }
149
150 pub fn distance_value(&self) -> f64 {
152 self.distance.value()
153 }
154
155 pub fn volatility_value(&self) -> f64 {
157 self.volatility.value()
158 }
159}
160
161