1pub mod betweenness;
2pub mod bridges;
3pub mod change_propagation;
4pub mod connected_components;
5pub mod degree;
6pub mod depth;
7pub mod graph_stats;
8pub mod impact_radius;
9pub mod pagerank;
10pub mod scc;
11pub mod transitive_reduction;
12
13use crate::config::Config;
14use crate::graph::Graph;
15use crate::lockfile::Lockfile;
16use std::path::Path;
17
18pub struct AnalysisContext<'a> {
21 pub graph: &'a Graph,
22 pub root: &'a Path,
23 pub config: &'a Config,
24 pub lockfile: Option<&'a Lockfile>,
25}
26
27pub fn all_analysis_names() -> &'static [&'static str] {
29 &[
30 "betweenness",
31 "bridges",
32 "change-propagation",
33 "connected-components",
34 "degree",
35 "depth",
36 "graph-stats",
37 "impact-radius",
38 "pagerank",
39 "scc",
40 "transitive-reduction",
41 ]
42}
43
44pub trait Analysis {
49 type Output: serde::Serialize;
50
51 fn name(&self) -> &str;
52
53 fn run(&self, ctx: &AnalysisContext) -> Self::Output;
54}
55
56pub struct EnrichedGraph {
59 pub graph: Graph,
60 pub betweenness: betweenness::BetweennessResult,
61 pub bridges: bridges::BridgesResult,
62 pub change_propagation: change_propagation::ChangePropagationResult,
63 pub connected_components: connected_components::ConnectedComponentsResult,
64 pub degree: degree::DegreeResult,
65 pub depth: depth::DepthResult,
66 pub graph_stats: graph_stats::GraphStatsResult,
67 pub impact_radius: impact_radius::ImpactRadiusResult,
68 pub pagerank: pagerank::PageRankResult,
69 pub scc: scc::SccResult,
70 pub transitive_reduction: transitive_reduction::TransitiveReductionResult,
71}
72
73pub fn enrich(
75 root: &Path,
76 config: &Config,
77 lockfile: Option<&Lockfile>,
78) -> anyhow::Result<EnrichedGraph> {
79 let graph = crate::graph::build_graph(root, config)?;
80 Ok(enrich_graph(graph, root, config, lockfile))
81}
82
83pub fn enrich_graph(
85 graph: Graph,
86 root: &Path,
87 config: &Config,
88 lockfile: Option<&Lockfile>,
89) -> EnrichedGraph {
90 let ctx = AnalysisContext {
91 graph: &graph,
92 root,
93 config,
94 lockfile,
95 };
96
97 let betweenness = betweenness::Betweenness.run(&ctx);
98 let bridges = bridges::Bridges.run(&ctx);
99 let change_propagation = change_propagation::ChangePropagation.run(&ctx);
100 let connected_components = connected_components::ConnectedComponents.run(&ctx);
101 let degree = degree::Degree.run(&ctx);
102 let depth = depth::Depth.run(&ctx);
103 let graph_stats = graph_stats::GraphStats.run(&ctx);
104 let impact_radius = impact_radius::ImpactRadius.run(&ctx);
105 let pagerank = pagerank::PageRank.run(&ctx);
106 let scc = scc::StronglyConnectedComponents.run(&ctx);
107 let transitive_reduction = transitive_reduction::TransitiveReduction.run(&ctx);
108
109 EnrichedGraph {
110 graph,
111 betweenness,
112 bridges,
113 change_propagation,
114 connected_components,
115 degree,
116 depth,
117 graph_stats,
118 impact_radius,
119 pagerank,
120 scc,
121 transitive_reduction,
122 }
123}