pub fn coupling(
store: &Store,
order: CouplingOrder,
limit: usize,
) -> Result<CouplingReport, StoreError>Expand description
Rank nodes by directed call coupling — fan-in (distinct callers) and
fan-out (distinct callees) over Calls edges — most-coupled first by
order, capped at limit (0 = unlimited).
Three deliberate counting rules, all of which change the numbers:
- Distinct counterparts, not edges. Edges are a set per
(src, dst, kind, provenance), which still admits parallelCallsedges between one pair at different provenances — aderivedextraction and aninferredsuggestion of the same call. Counting distinct counterpart keys makesfan_inmean “how many things depend on this”, which is the coupling question, rather than “how many layers asserted the dependency”. - Self-calls are excluded from both fans. Recursion is a real edge but
couples a node to nothing outside itself, and counting it would inflate
fan_inandfan_outfor the same node. It is reported separately asself_callsrather than silently dropped. - Cross-language call edges are excluded. Roteiro extracts no FFI, so a
Callsedge between two languages is never a call — see [same_language]. Reported ascross_language_calls.
Ordering is total and deterministic: by the chosen metric descending, then by
key ascending, so identical input yields byte-identical output.
§Precision
fan_in is exactly as precise as the Calls edges beneath it, and those are
resolved by simple name: a callee that is unique by bare name anywhere in
the repository binds to that definition, wherever it lives. So a single
same-language helper with a very common name absorbs every call to that name,
and its fan_in reads high for a reason that has nothing to do with design.
Excluding cross-language edges removes the worst of this, but not all of it.
Treat a large fan_in on a short, generically-named function as a question,
not a finding — which is also why this lens offers no CI gate.
§Errors
Returns StoreError on query failure.