use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use super::language::Language;
use super::span::Span;
use super::DEFAULT_DIMENSION;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u8)]
pub enum CodeUnitType {
Module = 0,
Symbol = 1,
Type = 2,
Function = 3,
Parameter = 4,
Import = 5,
Test = 6,
Doc = 7,
Config = 8,
Pattern = 9,
Trait = 10,
Impl = 11,
Macro = 12,
}
impl CodeUnitType {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(Self::Module),
1 => Some(Self::Symbol),
2 => Some(Self::Type),
3 => Some(Self::Function),
4 => Some(Self::Parameter),
5 => Some(Self::Import),
6 => Some(Self::Test),
7 => Some(Self::Doc),
8 => Some(Self::Config),
9 => Some(Self::Pattern),
10 => Some(Self::Trait),
11 => Some(Self::Impl),
12 => Some(Self::Macro),
_ => None,
}
}
pub fn is_callable(&self) -> bool {
matches!(self, Self::Function | Self::Macro)
}
pub fn is_container(&self) -> bool {
matches!(self, Self::Module | Self::Type | Self::Trait | Self::Impl)
}
pub fn label(&self) -> &'static str {
match self {
Self::Module => "module",
Self::Symbol => "symbol",
Self::Type => "type",
Self::Function => "function",
Self::Parameter => "parameter",
Self::Import => "import",
Self::Test => "test",
Self::Doc => "doc",
Self::Config => "config",
Self::Pattern => "pattern",
Self::Trait => "trait",
Self::Impl => "impl",
Self::Macro => "macro",
}
}
}
impl std::fmt::Display for CodeUnitType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.label())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u8)]
pub enum Visibility {
Public = 0,
Private = 1,
Internal = 2,
Protected = 3,
Unknown = 255,
}
impl Visibility {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(Self::Public),
1 => Some(Self::Private),
2 => Some(Self::Internal),
3 => Some(Self::Protected),
255 => Some(Self::Unknown),
_ => None,
}
}
}
impl std::fmt::Display for Visibility {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Public => write!(f, "public"),
Self::Private => write!(f, "private"),
Self::Internal => write!(f, "internal"),
Self::Protected => write!(f, "protected"),
Self::Unknown => write!(f, "unknown"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CodeUnit {
pub id: u64,
pub unit_type: CodeUnitType,
pub language: Language,
pub name: String,
pub qualified_name: String,
pub file_path: PathBuf,
pub span: Span,
pub signature: Option<String>,
pub doc_summary: Option<String>,
pub visibility: Visibility,
pub complexity: u32,
pub is_async: bool,
pub is_generator: bool,
pub created_at: u64,
pub last_modified: u64,
pub change_count: u32,
pub stability_score: f32,
pub collective_usage: u64,
pub content_hash: [u8; 32],
pub feature_vec: Vec<f32>,
pub edge_offset: u64,
pub edge_count: u32,
}
impl CodeUnit {
pub fn new(
unit_type: CodeUnitType,
language: Language,
name: String,
qualified_name: String,
file_path: PathBuf,
span: Span,
) -> Self {
let now = crate::types::now_micros();
Self {
id: 0,
unit_type,
language,
name,
qualified_name,
file_path,
span,
signature: None,
doc_summary: None,
visibility: Visibility::Unknown,
complexity: 0,
is_async: false,
is_generator: false,
created_at: now,
last_modified: now,
change_count: 0,
stability_score: 1.0,
collective_usage: 0,
content_hash: [0u8; 32],
feature_vec: vec![0.0; DEFAULT_DIMENSION],
edge_offset: 0,
edge_count: 0,
}
}
}
pub struct CodeUnitBuilder {
inner: CodeUnit,
}
impl CodeUnitBuilder {
pub fn new(
unit_type: CodeUnitType,
language: Language,
name: impl Into<String>,
qualified_name: impl Into<String>,
file_path: impl Into<PathBuf>,
span: Span,
) -> Self {
Self {
inner: CodeUnit::new(
unit_type,
language,
name.into(),
qualified_name.into(),
file_path.into(),
span,
),
}
}
pub fn signature(mut self, sig: impl Into<String>) -> Self {
self.inner.signature = Some(sig.into());
self
}
pub fn doc(mut self, doc: impl Into<String>) -> Self {
self.inner.doc_summary = Some(doc.into());
self
}
pub fn visibility(mut self, vis: Visibility) -> Self {
self.inner.visibility = vis;
self
}
pub fn complexity(mut self, c: u32) -> Self {
self.inner.complexity = c;
self
}
pub fn async_fn(mut self) -> Self {
self.inner.is_async = true;
self
}
pub fn generator(mut self) -> Self {
self.inner.is_generator = true;
self
}
pub fn feature_vec(mut self, vec: Vec<f32>) -> Self {
self.inner.feature_vec = vec;
self
}
pub fn content_hash(mut self, hash: [u8; 32]) -> Self {
self.inner.content_hash = hash;
self
}
pub fn timestamps(mut self, created: u64, modified: u64) -> Self {
self.inner.created_at = created;
self.inner.last_modified = modified;
self
}
pub fn build(self) -> CodeUnit {
self.inner
}
}