Skip to main content

sdivi_snapshot/
change_coupling.rs

1//! Change-coupling result types stored in [`super::snapshot::Snapshot`].
2
3use serde::{Deserialize, Serialize};
4
5/// A single file-pair that co-changes above the configured minimum frequency.
6///
7/// # Examples
8///
9/// ```rust
10/// use sdivi_snapshot::change_coupling::CoChangePair;
11///
12/// let pair = CoChangePair {
13///     source: "src/a.rs".to_string(),
14///     target: "src/b.rs".to_string(),
15///     frequency: 0.8,
16///     cochange_count: 4,
17/// };
18/// assert!(pair.source < pair.target);
19/// ```
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
21pub struct CoChangePair {
22    /// The lexicographically smaller file path (always `source < target`).
23    pub source: String,
24    /// The lexicographically larger file path.
25    pub target: String,
26    /// Co-change frequency: `cochange_count / commits_analyzed`.
27    pub frequency: f64,
28    /// Number of commits in the analysis window that touched both files.
29    pub cochange_count: u32,
30}
31
32/// Result of the change-coupling analysis for one snapshot.
33///
34/// `None` in the snapshot when the repo has no git history or
35/// `history_depth = 0` was configured.
36///
37/// # Examples
38///
39/// ```rust
40/// use sdivi_snapshot::change_coupling::ChangeCouplingResult;
41///
42/// let result = ChangeCouplingResult {
43///     pairs: vec![],
44///     commits_analyzed: 0,
45///     distinct_files_touched: 0,
46/// };
47/// assert_eq!(result.commits_analyzed, 0);
48/// ```
49#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
50pub struct ChangeCouplingResult {
51    /// File pairs whose co-change frequency meets `min_frequency` and
52    /// whose `cochange_count >= 2`. Sorted by `(source, target)`.
53    pub pairs: Vec<CoChangePair>,
54    /// Number of commits actually analyzed (≤ `history_depth`).
55    pub commits_analyzed: u32,
56    /// Count of unique file paths that appear in at least one analyzed commit.
57    pub distinct_files_touched: u32,
58}