use serde::{Deserialize, Serialize};
use crate::types::AcbError;
use crate::types::AcbResult;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MistakeCategory {
BugPattern,
PerformanceAntiPattern,
SecurityVulnerability,
ApiMisuse,
CodeSmell,
}
impl std::fmt::Display for MistakeCategory {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::BugPattern => write!(f, "bug-pattern"),
Self::PerformanceAntiPattern => write!(f, "performance-anti-pattern"),
Self::SecurityVulnerability => write!(f, "security-vulnerability"),
Self::ApiMisuse => write!(f, "api-misuse"),
Self::CodeSmell => write!(f, "code-smell"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MistakeReport {
pub category: MistakeCategory,
pub description: String,
pub pattern_signature: String,
pub suggestion: String,
pub severity: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollectiveDelta {
pub version: u32,
pub delta_id: String,
pub created_at: u64,
pub source_id: String,
pub patterns: Vec<DeltaPattern>,
pub mistakes: Vec<MistakeReport>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeltaPattern {
pub name: String,
pub language: String,
pub signature: String,
pub occurrence_count: u32,
pub confidence: f32,
}
impl CollectiveDelta {
pub fn new(source_id: String) -> Self {
let now = crate::types::now_micros();
Self {
version: 1,
delta_id: String::new(),
created_at: now,
source_id,
patterns: Vec::new(),
mistakes: Vec::new(),
}
}
pub fn add_pattern(&mut self, pattern: DeltaPattern) {
self.patterns.push(pattern);
}
pub fn add_mistake(&mut self, mistake: MistakeReport) {
self.mistakes.push(mistake);
}
pub fn finalize(&mut self) -> AcbResult<()> {
let json = serde_json::to_vec(self)
.map_err(|e| AcbError::Compression(format!("Failed to serialize delta: {}", e)))?;
let hash = blake3::hash(&json);
self.delta_id = hash.to_hex().to_string();
Ok(())
}
pub fn compress(&self) -> AcbResult<Vec<u8>> {
let json = serde_json::to_vec(self)
.map_err(|e| AcbError::Compression(format!("Failed to serialize delta: {}", e)))?;
let compressed = lz4_flex::compress_prepend_size(&json);
Ok(compressed)
}
pub fn decompress(data: &[u8]) -> AcbResult<Self> {
let decompressed = lz4_flex::decompress_size_prepended(data)
.map_err(|e| AcbError::Compression(format!("Failed to decompress delta: {}", e)))?;
let delta: CollectiveDelta = serde_json::from_slice(&decompressed)
.map_err(|e| AcbError::Compression(format!("Failed to deserialize delta: {}", e)))?;
Ok(delta)
}
pub fn is_empty(&self) -> bool {
self.patterns.is_empty() && self.mistakes.is_empty()
}
}