use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Language {
Python,
TypeScript,
JavaScript,
Go,
Rust,
Java,
C,
Cpp,
Ruby,
CSharp,
Kotlin,
Swift,
Scala,
Php,
Lua,
Elixir,
Haskell,
Ocaml,
Markdown,
Text,
Yaml,
Toml,
Json,
Dockerfile,
Makefile,
Shell,
Powershell,
AsciiDoc,
Org,
}
impl FromStr for Language {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"python" | "py" => Ok(Language::Python),
"typescript" | "ts" => Ok(Language::TypeScript),
"javascript" | "js" => Ok(Language::JavaScript),
"go" => Ok(Language::Go),
"rust" | "rs" => Ok(Language::Rust),
"java" => Ok(Language::Java),
"c" => Ok(Language::C),
"cpp" | "c++" => Ok(Language::Cpp),
"ruby" | "rb" => Ok(Language::Ruby),
"csharp" | "c#" | "cs" => Ok(Language::CSharp),
"kotlin" | "kt" => Ok(Language::Kotlin),
"swift" => Ok(Language::Swift),
"scala" => Ok(Language::Scala),
"php" => Ok(Language::Php),
"lua" => Ok(Language::Lua),
"elixir" | "ex" => Ok(Language::Elixir),
"haskell" | "hs" => Ok(Language::Haskell),
"ocaml" | "ml" => Ok(Language::Ocaml),
"markdown" | "md" => Ok(Language::Markdown),
"text" | "txt" => Ok(Language::Text),
"yaml" | "yml" => Ok(Language::Yaml),
"toml" => Ok(Language::Toml),
"json" => Ok(Language::Json),
"dockerfile" => Ok(Language::Dockerfile),
"makefile" => Ok(Language::Makefile),
"shell" | "sh" | "bash" => Ok(Language::Shell),
"powershell" | "ps1" => Ok(Language::Powershell),
"asciidoc" | "adoc" => Ok(Language::AsciiDoc),
"org" => Ok(Language::Org),
_ => Err(format!("Unknown language: {}", s)),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum UnitType {
Function,
Method,
Class,
Document,
Section,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CodeUnit {
pub name: String,
pub qualified_name: String,
pub file: PathBuf,
pub line: usize,
pub language: Language,
pub unit_type: UnitType,
pub signature: String,
pub docstring: Option<String>,
pub parameters: Vec<String>,
pub return_type: Option<String>,
pub calls: Vec<String>,
pub called_by: Vec<String>,
pub complexity: usize,
pub has_loops: bool,
pub has_branches: bool,
pub has_error_handling: bool,
pub variables: Vec<String>,
pub imports: Vec<String>,
pub code_preview: String,
}
impl CodeUnit {
pub fn new(
name: String,
file: PathBuf,
line: usize,
language: Language,
unit_type: UnitType,
parent_class: Option<&str>,
) -> Self {
let qualified_name = match parent_class {
Some(c) => format!("{}::{}::{}", file.display(), c, name),
None => format!("{}::{}", file.display(), name),
};
Self {
name,
qualified_name,
file,
line,
language,
unit_type,
signature: String::new(),
docstring: None,
parameters: Vec::new(),
return_type: None,
calls: Vec::new(),
called_by: Vec::new(),
complexity: 1,
has_loops: false,
has_branches: false,
has_error_handling: false,
variables: Vec::new(),
imports: Vec::new(),
code_preview: String::new(),
}
}
}