1use indexmap::IndexMap;
4use serde::{Deserialize, Serialize};
5
6pub const PROJECT_GRAPH_VERSION: u32 = 1;
8
9#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
11#[serde(rename_all = "snake_case")]
12pub enum GraphEdgeKind {
13 Calls,
15 Imports,
17 Inherits,
19 Implements,
21 Reads,
23 Writes,
25 Constructs,
27 Returns,
29 Throws,
31 DependsOn,
33 Tests,
35 Exports,
37}
38
39pub type Relationship = GraphEdgeKind;
41
42#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
44#[serde(rename_all = "snake_case")]
45pub enum GraphNodeKind {
46 Module,
48 Function,
50 Class,
52 Type,
54 Package,
56 Test,
58 Entrypoint,
60 Resource,
62 Config,
64}
65
66#[derive(Clone, Debug, Serialize, Deserialize)]
68pub struct GraphNode {
69 pub id: String,
71 pub kind: GraphNodeKind,
73 pub name: String,
75 pub file: Option<String>,
77 pub attrs: IndexMap<String, serde_json::Value>,
79}
80
81#[derive(Clone, Debug, Serialize, Deserialize)]
83pub struct GraphEdge {
84 pub from: String,
86 pub to: String,
88 pub kind: GraphEdgeKind,
90}
91
92#[derive(Clone, Debug, Serialize, Deserialize)]
94pub struct ProjectFile {
95 pub path: String,
97 pub role: String,
99 pub language: Option<String>,
101 pub bytes: u64,
103}
104
105#[derive(Clone, Debug, Serialize, Deserialize)]
107pub struct DependencyRef {
108 pub ecosystem: String,
110 pub name: String,
112 pub version: Option<String>,
114 pub dev: bool,
116}
117
118#[derive(Clone, Debug, Serialize, Deserialize)]
120pub struct Entrypoint {
121 pub path: String,
123 pub kind: String,
125}
126
127#[derive(Clone, Debug, Serialize, Deserialize)]
129pub struct ProjectGraph {
130 pub version: u32,
132 pub name: String,
134 pub files: Vec<ProjectFile>,
136 pub packages: Vec<DependencyRef>,
138 pub entrypoints: Vec<Entrypoint>,
140 pub nodes: IndexMap<String, GraphNode>,
142 pub edges: Vec<GraphEdge>,
144 pub build_system: Option<String>,
146 pub test_framework: Option<String>,
148}
149
150impl ProjectGraph {
151 pub fn new(name: impl Into<String>) -> Self {
153 Self {
154 version: PROJECT_GRAPH_VERSION,
155 name: name.into(),
156 files: Vec::new(),
157 packages: Vec::new(),
158 entrypoints: Vec::new(),
159 nodes: IndexMap::new(),
160 edges: Vec::new(),
161 build_system: None,
162 test_framework: None,
163 }
164 }
165
166 pub fn source_file_count(&self) -> usize {
168 self.files.iter().filter(|f| f.role == "source").count()
169 }
170
171 pub fn test_file_count(&self) -> usize {
173 self.files.iter().filter(|f| f.role == "test").count()
174 }
175}
176
177pub type ProjectPackage = DependencyRef;