use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Language {
Rust,
Python,
JavaScript,
TypeScript,
Java,
CSharp,
Cpp,
C,
Go,
Php,
Kotlin,
Swift,
}
impl fmt::Display for Language {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Language::Rust => write!(f, "Rust"),
Language::Python => write!(f, "Python"),
Language::JavaScript => write!(f, "JavaScript"),
Language::TypeScript => write!(f, "TypeScript"),
Language::Java => write!(f, "Java"),
Language::CSharp => write!(f, "C#"),
Language::Cpp => write!(f, "C++"),
Language::C => write!(f, "C"),
Language::Go => write!(f, "Go"),
Language::Php => write!(f, "PHP"),
Language::Kotlin => write!(f, "Kotlin"),
Language::Swift => write!(f, "Swift"),
}
}
}
impl FromStr for Language {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"rust" => Ok(Language::Rust),
"python" => Ok(Language::Python),
"javascript" | "js" => Ok(Language::JavaScript),
"typescript" | "ts" => Ok(Language::TypeScript),
"java" => Ok(Language::Java),
"csharp" | "c#" => Ok(Language::CSharp),
"cpp" | "c++" => Ok(Language::Cpp),
"c" => Ok(Language::C),
"go" => Ok(Language::Go),
"php" => Ok(Language::Php),
"kotlin" | "kt" => Ok(Language::Kotlin),
"swift" => Ok(Language::Swift),
_ => Err(format!("Unknown language: {s}")),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FunctionMetrics {
pub name: String,
pub start_line: usize,
pub end_line: usize,
pub cognitive: u64,
pub cyclomatic: u64,
pub sloc: u64,
pub exceeds_threshold: Option<bool>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FileReport {
pub path: String,
pub language: Language,
pub functions: Vec<FunctionMetrics>,
pub file_cognitive: u64,
pub file_cyclomatic: u64,
pub file_sloc: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AnalysisConfig {
pub cognitive_threshold: Option<u64>,
pub include_methods: bool,
}
impl Default for AnalysisConfig {
fn default() -> Self {
Self {
cognitive_threshold: None,
include_methods: true,
}
}
}