use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
pub const PROJECT_GRAPH_VERSION: u32 = 1;
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GraphEdgeKind {
Calls,
Imports,
Inherits,
Implements,
Reads,
Writes,
Constructs,
Returns,
Throws,
DependsOn,
Tests,
Exports,
}
pub type Relationship = GraphEdgeKind;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GraphNodeKind {
Module,
Function,
Class,
Type,
Package,
Test,
Entrypoint,
Resource,
Config,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GraphNode {
pub id: String,
pub kind: GraphNodeKind,
pub name: String,
pub file: Option<String>,
pub attrs: IndexMap<String, serde_json::Value>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GraphEdge {
pub from: String,
pub to: String,
pub kind: GraphEdgeKind,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ProjectFile {
pub path: String,
pub role: String,
pub language: Option<String>,
pub bytes: u64,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DependencyRef {
pub ecosystem: String,
pub name: String,
pub version: Option<String>,
pub dev: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Entrypoint {
pub path: String,
pub kind: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ProjectGraph {
pub version: u32,
pub name: String,
pub files: Vec<ProjectFile>,
pub packages: Vec<DependencyRef>,
pub entrypoints: Vec<Entrypoint>,
pub nodes: IndexMap<String, GraphNode>,
pub edges: Vec<GraphEdge>,
pub build_system: Option<String>,
pub test_framework: Option<String>,
}
impl ProjectGraph {
pub fn new(name: impl Into<String>) -> Self {
Self {
version: PROJECT_GRAPH_VERSION,
name: name.into(),
files: Vec::new(),
packages: Vec::new(),
entrypoints: Vec::new(),
nodes: IndexMap::new(),
edges: Vec::new(),
build_system: None,
test_framework: None,
}
}
pub fn source_file_count(&self) -> usize {
self.files.iter().filter(|f| f.role == "source").count()
}
pub fn test_file_count(&self) -> usize {
self.files.iter().filter(|f| f.role == "test").count()
}
}
pub type ProjectPackage = DependencyRef;