use serde::Serialize;
use std::path::PathBuf;
use crate::analysis::aggregator::FileAnalysis;
#[derive(Debug, Clone, Serialize)]
pub struct Violation {
pub row: usize,
pub message: String,
pub law: &'static str,
pub details: Option<ViolationDetails>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct ViolationDetails {
pub function_name: Option<String>,
pub analysis: Vec<String>,
pub suggestion: Option<String>,
}
impl Violation {
#[must_use]
pub fn simple(row: usize, message: String, law: &'static str) -> Self {
Self {
row,
message,
law,
details: None,
}
}
#[must_use]
pub fn with_details(
row: usize,
message: String,
law: &'static str,
details: ViolationDetails,
) -> Self {
Self {
row,
message,
law,
details: Some(details),
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct FileReport {
pub path: PathBuf,
pub token_count: usize,
pub complexity_score: usize,
pub violations: Vec<Violation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub analysis: Option<FileAnalysis>,
}
impl FileReport {
#[must_use]
pub fn is_clean(&self) -> bool {
self.violations.is_empty()
}
#[must_use]
pub fn violation_count(&self) -> usize {
self.violations.len()
}
}
#[derive(Debug, Clone, Default, Serialize)]
pub struct ScanReport {
pub files: Vec<FileReport>,
pub total_tokens: usize,
pub total_violations: usize,
pub duration_ms: u128,
}
impl ScanReport {
#[must_use]
pub fn has_errors(&self) -> bool {
self.total_violations > 0
}
#[must_use]
pub fn clean_file_count(&self) -> usize {
self.files.iter().filter(|f| f.is_clean()).count()
}
#[must_use]
pub fn is_small_codebase(&self) -> bool {
crate::analysis::Engine::small_codebase_threshold() >= self.files.len()
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CommandResult {
pub command: String,
pub exit_code: i32,
pub stdout: String,
pub stderr: String,
pub duration_ms: u64,
}
#[derive(Debug, Clone, Serialize)]
pub struct CheckReport {
pub scan: ScanReport,
pub commands: Vec<CommandResult>,
pub passed: bool,
}