Skip to main content

drft/analyses/
mod.rs

1pub mod betweenness;
2pub mod bridges;
3pub mod change_propagation;
4pub mod connected_components;
5pub mod degree;
6pub mod depth;
7pub mod graph_boundaries;
8pub mod graph_stats;
9pub mod impact_radius;
10pub mod pagerank;
11pub mod scc;
12pub mod transitive_reduction;
13
14use crate::config::Config;
15use crate::graph::Graph;
16use crate::lockfile::Lockfile;
17use std::path::Path;
18
19/// Context passed to every analysis, providing access to the graph,
20/// filesystem root, config, and optional lockfile.
21pub struct AnalysisContext<'a> {
22    pub graph: &'a Graph,
23    pub root: &'a Path,
24    pub config: &'a Config,
25    pub lockfile: Option<&'a Lockfile>,
26}
27
28/// All known analysis names, sorted alphabetically.
29pub fn all_analysis_names() -> &'static [&'static str] {
30    &[
31        "betweenness",
32        "bridges",
33        "change-propagation",
34        "connected-components",
35        "degree",
36        "depth",
37        "graph-boundaries",
38        "graph-stats",
39        "impact-radius",
40        "pagerank",
41        "scc",
42        "transitive-reduction",
43    ]
44}
45
46/// An analysis computes structured data about the graph.
47/// Rules consume analysis results and map them to diagnostics.
48/// Metrics extract scalar values from analysis results.
49/// See [`docs/analyses`](../../docs/analyses/README.md) for conceptual documentation on each analysis.
50pub trait Analysis {
51    type Output: serde::Serialize;
52
53    fn name(&self) -> &str;
54
55    fn run(&self, ctx: &AnalysisContext) -> Self::Output;
56}
57
58/// The complete, enriched graph. Built once, enriched once.
59/// Carries the graph plus all structural analyses unconditionally.
60pub struct EnrichedGraph {
61    pub graph: Graph,
62    pub betweenness: betweenness::BetweennessResult,
63    pub bridges: bridges::BridgesResult,
64    pub change_propagation: change_propagation::ChangePropagationResult,
65    pub connected_components: connected_components::ConnectedComponentsResult,
66    pub degree: degree::DegreeResult,
67    pub depth: depth::DepthResult,
68    pub graph_boundaries: graph_boundaries::GraphBoundariesResult,
69    pub graph_stats: graph_stats::GraphStatsResult,
70    pub impact_radius: impact_radius::ImpactRadiusResult,
71    pub pagerank: pagerank::PageRankResult,
72    pub scc: scc::SccResult,
73    pub transitive_reduction: transitive_reduction::TransitiveReductionResult,
74}
75
76/// Build an enriched graph: construct the graph, then run all analyses unconditionally.
77pub fn enrich(
78    root: &Path,
79    config: &Config,
80    lockfile: Option<&Lockfile>,
81) -> anyhow::Result<EnrichedGraph> {
82    let graph = crate::graph::build_graph(root, config)?;
83    Ok(enrich_graph(graph, root, config, lockfile))
84}
85
86/// Enrich a pre-built graph with all analyses.
87pub fn enrich_graph(
88    graph: Graph,
89    root: &Path,
90    config: &Config,
91    lockfile: Option<&Lockfile>,
92) -> EnrichedGraph {
93    let ctx = AnalysisContext {
94        graph: &graph,
95        root,
96        config,
97        lockfile,
98    };
99
100    let betweenness = betweenness::Betweenness.run(&ctx);
101    let bridges = bridges::Bridges.run(&ctx);
102    let change_propagation = change_propagation::ChangePropagation.run(&ctx);
103    let connected_components = connected_components::ConnectedComponents.run(&ctx);
104    let degree = degree::Degree.run(&ctx);
105    let depth = depth::Depth.run(&ctx);
106    let graph_boundaries = graph_boundaries::GraphBoundaries.run(&ctx);
107    let graph_stats = graph_stats::GraphStats.run(&ctx);
108    let impact_radius = impact_radius::ImpactRadius.run(&ctx);
109    let pagerank = pagerank::PageRank.run(&ctx);
110    let scc = scc::StronglyConnectedComponents.run(&ctx);
111    let transitive_reduction = transitive_reduction::TransitiveReduction.run(&ctx);
112
113    EnrichedGraph {
114        graph,
115        betweenness,
116        bridges,
117        change_propagation,
118        connected_components,
119        degree,
120        depth,
121        graph_boundaries,
122        graph_stats,
123        impact_radius,
124        pagerank,
125        scc,
126        transitive_reduction,
127    }
128}