use std::{
fmt::{Display, Formatter},
path::PathBuf,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct CodeDossier {
pub name: String,
pub file_path: PathBuf,
#[schemars(skip)]
#[serde(default)]
pub source_summary: String,
pub code_purpose: CodePurpose,
pub importance_score: f64,
pub description: Option<String>,
pub functions: Vec<String>,
pub interfaces: Vec<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct CodeInsight {
pub code_dossier: CodeDossier,
pub detailed_description: String,
pub responsibilities: Vec<String>,
pub interfaces: Vec<InterfaceInfo>,
pub dependencies: Vec<Dependency>,
pub complexity_metrics: CodeComplexity,
}
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct InterfaceInfo {
pub name: String,
pub interface_type: String, pub visibility: String, pub parameters: Vec<ParameterInfo>,
pub return_type: Option<String>,
pub description: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct ParameterInfo {
pub name: String,
pub param_type: String,
pub is_optional: bool,
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct Dependency {
pub name: String,
pub path: Option<String>,
pub is_external: bool,
pub line_number: Option<usize>,
pub dependency_type: String, pub version: Option<String>,
}
impl Display for Dependency {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
format!(
"(name={}, path={}, is_external={},dependency_type={})",
self.name,
self.path.as_deref().unwrap_or_default(),
self.is_external,
self.dependency_type
)
)
}
}
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
pub struct CodeComplexity {
pub cyclomatic_complexity: f64,
pub lines_of_code: usize,
pub number_of_functions: usize,
pub number_of_classes: usize,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum CodePurpose {
Entry,
Agent,
Page,
Widget,
SpecificFeature,
Model,
Types,
Tool,
Util,
Config,
Middleware,
Plugin,
Router,
Database,
Api,
Controller,
Service,
Module,
Lib,
Test,
Doc,
Dao,
Context,
Other,
}
impl CodePurpose {
pub fn display_name(&self) -> &'static str {
match self {
CodePurpose::Entry => "项目执行入口",
CodePurpose::Agent => "智能Agent",
CodePurpose::Page => "前端UI页面",
CodePurpose::Widget => "前端UI组件",
CodePurpose::SpecificFeature => "用于处理实现特定逻辑功能",
CodePurpose::Model => "数据类型或模型",
CodePurpose::Util => "基础工具函数",
CodePurpose::Tool => "特定场景下的功能工具代码",
CodePurpose::Config => "配置",
CodePurpose::Middleware => "中间件",
CodePurpose::Plugin => "插件",
CodePurpose::Router => "路由组件",
CodePurpose::Database => "数据库组件",
CodePurpose::Api => "各类接口定义",
CodePurpose::Controller => "Controller组件",
CodePurpose::Service => "Service组件",
CodePurpose::Module => "模块组件",
CodePurpose::Lib => "依赖库",
CodePurpose::Test => "测试组件",
CodePurpose::Doc => "文档组件",
CodePurpose::Other => "其他组件",
CodePurpose::Types => "程序接口定义",
CodePurpose::Dao => "数据访问层组件",
CodePurpose::Context => "上下文组件",
}
}
}
impl Display for CodePurpose {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.display_name())
}
}
impl Default for CodePurpose {
fn default() -> Self {
CodePurpose::Other
}
}
pub struct CodePurposeMapper;
impl CodePurposeMapper {
pub fn map_by_path_and_name(file_path: &str, file_name: &str) -> CodePurpose {
let path_lower = file_path.to_lowercase();
let name_lower = file_name.to_lowercase();
if path_lower.contains("/pages/")
|| path_lower.contains("/views/")
|| path_lower.contains("/screens/")
{
return CodePurpose::Page;
}
if path_lower.contains("/components/")
|| path_lower.contains("/widgets/")
|| path_lower.contains("/ui/")
{
return CodePurpose::Widget;
}
if path_lower.contains("/models/")
|| path_lower.contains("/entities/")
|| path_lower.contains("/data/")
{
return CodePurpose::Model;
}
if path_lower.contains("/utils/")
|| path_lower.contains("/utilities/")
|| path_lower.contains("/helpers/")
{
return CodePurpose::Util;
}
if path_lower.contains("/config/")
|| path_lower.contains("/configs/")
|| path_lower.contains("/settings/")
{
return CodePurpose::Config;
}
if path_lower.contains("/middleware/") || path_lower.contains("/middlewares/") {
return CodePurpose::Middleware;
}
if path_lower.contains("/plugin/") {
return CodePurpose::Plugin;
}
if path_lower.contains("/routes/")
|| path_lower.contains("/router/")
|| path_lower.contains("/routing/")
{
return CodePurpose::Router;
}
if path_lower.contains("/database/")
|| path_lower.contains("/db/")
|| path_lower.contains("/storage/")
{
return CodePurpose::Database;
}
if path_lower.contains("/dao/")
|| path_lower.contains("/repository/")
|| path_lower.contains("/persistence/")
{
return CodePurpose::Dao;
}
if path_lower.contains("/context") || path_lower.contains("/ctx/") {
return CodePurpose::Context;
}
if path_lower.contains("/api")
|| path_lower.contains("/endpoint")
|| path_lower.contains("/controller")
|| path_lower.contains("/native_module")
|| path_lower.contains("/bridge")
{
return CodePurpose::Api;
}
if path_lower.contains("/test/")
|| path_lower.contains("/tests/")
|| path_lower.contains("/__tests__/")
{
return CodePurpose::Test;
}
if path_lower.contains("/docs/")
|| path_lower.contains("/doc/")
|| path_lower.contains("/documentation/")
{
return CodePurpose::Doc;
}
if name_lower.contains("main") || name_lower.contains("index") || name_lower.contains("app")
{
return CodePurpose::Entry;
}
if name_lower.contains("page")
|| name_lower.contains("view")
|| name_lower.contains("screen")
{
return CodePurpose::Page;
}
if name_lower.contains("component") || name_lower.contains("widget") {
return CodePurpose::Widget;
}
if name_lower.contains("model") || name_lower.contains("entity") {
return CodePurpose::Model;
}
if name_lower.contains("util") {
return CodePurpose::Util;
}
if name_lower.contains("config") || name_lower.contains("setting") {
return CodePurpose::Config;
}
if name_lower.contains("middleware") {
return CodePurpose::Middleware;
}
if name_lower.contains("plugin") {
return CodePurpose::Plugin;
}
if name_lower.contains("route") {
return CodePurpose::Router;
}
if name_lower.contains("database") {
return CodePurpose::Database;
}
if name_lower.contains("repository") || name_lower.contains("persistence") {
return CodePurpose::Dao;
}
if name_lower.contains("context") || name_lower.contains("ctx") {
return CodePurpose::Context;
}
if name_lower.contains("api") || name_lower.contains("endpoint") {
return CodePurpose::Api;
}
if name_lower.contains("test") || name_lower.contains("spec") {
return CodePurpose::Test;
}
if name_lower.contains("readme") || name_lower.contains("doc") {
return CodePurpose::Doc;
}
CodePurpose::Other
}
}