use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum SymbolKind {
Function,
Method,
#[serde(rename = "class")]
ClassDecl,
#[serde(rename = "struct")]
StructDecl,
#[serde(rename = "enum")]
EnumDecl,
#[serde(rename = "protocol")]
ProtocolDecl,
#[serde(rename = "interface")]
InterfaceDecl,
#[serde(rename = "typealias")]
TypeAlias,
Property,
Variable,
Constant,
Module,
Mark,
Todo,
Fixme,
Other,
}
impl SymbolKind {
pub fn is_type_definition(self) -> bool {
matches!(
self,
SymbolKind::ClassDecl
| SymbolKind::StructDecl
| SymbolKind::EnumDecl
| SymbolKind::ProtocolDecl
| SymbolKind::InterfaceDecl
)
}
pub fn keyword(self) -> &'static str {
match self {
SymbolKind::Function => "function",
SymbolKind::Method => "method",
SymbolKind::ClassDecl => "class",
SymbolKind::StructDecl => "struct",
SymbolKind::EnumDecl => "enum",
SymbolKind::ProtocolDecl => "protocol",
SymbolKind::InterfaceDecl => "interface",
SymbolKind::TypeAlias => "typealias",
SymbolKind::Property => "property",
SymbolKind::Variable => "variable",
SymbolKind::Constant => "constant",
SymbolKind::Module => "module",
SymbolKind::Mark => "mark",
SymbolKind::Todo => "todo",
SymbolKind::Fixme => "fixme",
SymbolKind::Other => "other",
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct FileRecord {
pub id: String,
pub relative_path: String,
pub file_name: String,
pub language: String,
pub line_count: usize,
pub size_bytes: u64,
pub last_modified_unix_ms: i64,
pub imports: Vec<String>,
pub churn_score: f64,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub corresponding_test_file: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SymbolRecord {
pub id: String,
pub name: String,
pub kind: SymbolKind,
pub file_path: String,
pub line: usize,
pub signature: String,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub container: Option<String>,
pub reference_count: usize,
pub importance_score: f64,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct FolderRecord {
pub id: String,
pub relative_path: String,
pub file_count: usize,
pub line_count: usize,
pub dominant_language: String,
pub key_symbol_names: Vec<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct LanguageStat {
pub name: String,
pub file_count: usize,
pub line_count: usize,
pub percentage: f64,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ProjectMetadata {
pub name: String,
pub root_path: String,
pub languages: Vec<LanguageStat>,
pub test_commands: std::collections::BTreeMap<String, String>,
pub detected_test_command: Option<String>,
pub code_patterns: Vec<String>,
pub total_files: usize,
pub total_lines: usize,
pub last_scanned_at: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DependencyEdge {
pub from_file: String,
pub to_module: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SubProject {
pub path: String,
pub name: String,
pub language: String,
pub project_marker: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
pub struct ScanDelta {
pub added: Vec<String>,
pub modified: Vec<String>,
pub removed: Vec<String>,
pub full_rescan: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ScanResult {
pub snapshot_token: String,
pub truncated: bool,
pub project: ProjectMetadata,
pub folders: Vec<FolderRecord>,
pub files: Vec<FileRecord>,
pub symbols: Vec<SymbolRecord>,
pub dependencies: Vec<DependencyEdge>,
pub sub_projects: Vec<SubProject>,
pub repo_map: String,
}