Skip to main content

code_ranker_graph/
level_graph.rs

1//! Per-level payload types: [`LevelGraph`] (one analysis level's structural
2//! graph + semantics dictionaries + computed cycles/stats/UI), [`LevelUi`]
3//! (computed UI hints), and [`CycleGroup`] (one classified SCC). These are the
4//! widely-imported model types; keeping them in their own module spreads their
5//! fan-in off the crate's `snapshot` artifact.
6
7use code_ranker_plugin_api::{
8    attrs::AttrValue,
9    edge::Edge,
10    level::{AttributeGroup, AttributeSpec, CycleKindSpec, EdgeKindSpec, Grouping, NodeKindSpec},
11    node::{Node, NodeId},
12};
13use serde::{Deserialize, Serialize};
14use std::collections::BTreeMap;
15
16/// UI hints for a level: which metrics to offer as table columns, summary rows,
17/// sort/size keys, and the default sort — computed by the orchestrator from the
18/// attributes actually present, so the viewer hardcodes none of it.
19#[derive(Debug, Clone, Default, Serialize, Deserialize)]
20pub struct LevelUi {
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub default_sort: Option<String>,
23    pub sort_metrics: Vec<String>,
24    pub size_metrics: Vec<String>,
25    pub card_metrics: Vec<String>,
26    pub columns: Vec<String>,
27    pub summary_metrics: Vec<String>,
28    /// How the viewer should cluster nodes (group by attribute `key`, or a named
29    /// `function`). Carried through from the plugin's level spec, pruned to a
30    /// valid attribute. Absent → the viewer uses its default `dir` grouper.
31    #[serde(default, skip_serializing_if = "Option::is_none")]
32    pub grouping: Option<Grouping>,
33}
34
35/// One strongly-connected component with ≥ 2 nodes, plus its classification
36/// (`"mutual"` for a 2-node SCC, `"chain"` for 3+). Node ids match the level graph.
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct CycleGroup {
39    pub kind: String,
40    pub nodes: Vec<NodeId>,
41}
42
43/// Everything for one analysis level: the structural graph, the semantics
44/// dictionaries that describe its vocabulary, and the computed cycles + stats.
45#[derive(Debug, Clone, Default, Serialize, Deserialize)]
46pub struct LevelGraph {
47    /// Edge kinds present at this level (keyed by kind), with `flow` semantics.
48    pub edge_kinds: BTreeMap<String, EdgeKindSpec>,
49    /// Node attribute dictionary (structural keys + appended computed metrics).
50    pub node_attributes: BTreeMap<String, AttributeSpec>,
51    /// Edge attribute dictionary.
52    pub edge_attributes: BTreeMap<String, AttributeSpec>,
53    /// Attribute group definitions referenced by `AttributeSpec.group`.
54    pub attribute_groups: BTreeMap<String, AttributeGroup>,
55    /// Node-kind vocabulary (label/colour/external).
56    pub node_kinds: BTreeMap<String, NodeKindSpec>,
57    /// Cycle-kind vocabulary.
58    pub cycle_kinds: BTreeMap<String, CycleKindSpec>,
59    pub nodes: Vec<Node>,
60    pub edges: Vec<Edge>,
61    /// SCCs with ≥ 2 members, classified by kind.
62    pub cycles: Vec<CycleGroup>,
63    /// Per-graph averages of numeric node attributes (flat, keyed by attr name).
64    pub stats: BTreeMap<String, AttrValue>,
65    /// Computed UI hints (column/sort/size/card ordering).
66    pub ui: LevelUi,
67}