Skip to main content

code_ranker_plugin_api/
lib.rs

1//! # code-ranker-plugin-api
2//!
3//! The contract everything in Code Ranker builds on: a **generic property-graph
4//! model** plus the [`LanguagePlugin`](plugin::LanguagePlugin) trait. This crate is the foundation — it
5//! depends on **nothing** else from Code Ranker and re-exports nothing. Every
6//! other crate (graph operations, complexity, language plugins, viewer, cli)
7//! depends on *this*.
8//!
9//! ## Model
10//!
11//! Analysis produces a [`Graph`](graph::Graph) of **[`Node`](node::Node)**s connected by **[`Edge`](edge::Edge)**s.
12//! A node is *anything we analyze*: today a source file (`kind == "file"`),
13//! tomorrow a folder, module, function, variable or line — with **no model
14//! change**. `kind` is a free-form [`String`] (the plugin's own vocabulary);
15//! the core never interprets it, it only stores and projects.
16//!
17//! Both nodes and edges carry free-form **[`Attributes`](attrs::Attributes)** (string key →
18//! scalar [`AttrValue`](attrs::AttrValue)). There is no fixed, file/language-specific field set:
19//! the plugin chooses keys (`path`, `loc`, `visibility`, `version`, or
20//! language-specific ones), the orchestrator adds computed keys (metrics,
21//! cycle), and the core reads only the keys it understands. Each level describes
22//! its keys with an [`AttributeSpec`](level::AttributeSpec) dictionary (type + label/hint), so the UI
23//! knows what each key means and what it can do with it.
24//!
25//! ## Responsibilities
26//!
27//! A [`LanguagePlugin`](plugin::LanguagePlugin) is a **pure parser**: it turns a workspace into nodes +
28//! edges at a requested level (by name; see [`Level`](level::Level)). It does **not**
29//! compute metrics — complexity / cycles / Henry-Kafura / stats are filled in
30//! centrally, for all languages, by the orchestrator. The plugin also describes
31//! its edge kinds ([`EdgeKindSpec`](level::EdgeKindSpec)) and attribute keys
32//! ([`AttributeSpec`](level::AttributeSpec)), so the core scores, draws and labels unknown
33//! kinds/keys without hardcoding their names.
34
35pub mod attrs;
36pub mod edge;
37pub mod graph;
38pub mod level;
39pub mod log;
40pub mod node;
41pub mod plugin;
42
43pub use attrs::{AttrValue, Attributes, ValueType};
44pub use edge::Edge;
45pub use graph::Graph;
46pub use level::{
47    AttributeGroup, AttributeSpec, CycleKindSpec, Direction, EdgeKindSpec, Level, NodeKindSpec,
48    SpecRow, Thresholds, attr_dict, group,
49};
50pub use node::{Node, NodeId};
51pub use plugin::{LanguagePlugin, Options, PluginInput, Preset};
52
53use std::collections::BTreeMap;
54
55/// The generic node-kind palette every file-based plugin seeds its level with:
56/// `file` (a project source unit, blue) and `external` (a third-party library,
57/// amber, flagged external). A plugin may recolor or add kinds.
58pub fn default_node_kinds() -> BTreeMap<String, NodeKindSpec> {
59    BTreeMap::from([
60        (
61            "file".to_string(),
62            NodeKindSpec {
63                label: Some("File".into()),
64                plural: Some("Files".into()),
65                fill: Some("#dbe9f4".into()),
66                stroke: Some("#4d6f9c".into()),
67                external: None,
68            },
69        ),
70        (
71            "external".to_string(),
72            NodeKindSpec {
73                label: Some("Library".into()),
74                plural: Some("Libraries".into()),
75                fill: Some("#f6e2c0".into()),
76                stroke: Some("#b3801f".into()),
77                external: Some(true),
78            },
79        ),
80    ])
81}
82
83/// The generic cycle-kind vocabulary (`mutual` / `chain`).
84pub fn default_cycle_kinds() -> BTreeMap<String, CycleKindSpec> {
85    let k = |label: &str, desc: &str| CycleKindSpec {
86        label: Some(label.to_string()),
87        description: Some(desc.to_string()),
88    };
89    BTreeMap::from([
90        (
91            "mutual".to_string(),
92            k(
93                "Mutual",
94                "Two nodes that directly depend on each other (A ↔ B).",
95            ),
96        ),
97        (
98            "chain".to_string(),
99            k(
100                "Chain",
101                "Three or more nodes forming a dependency cycle (A → B → C → A).",
102            ),
103        ),
104    ])
105}