use crate::snapshot::MemorySnapshot;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalysisResult {
pub analyzer_name: String,
pub issue_count: usize,
pub severity: Severity,
pub description: String,
pub findings: Vec<Finding>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Finding {
pub issue_type: String,
pub description: String,
pub ptr: Option<usize>,
pub size: Option<usize>,
pub context: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Severity {
Info,
Warning,
Error,
Critical,
}
impl fmt::Display for Severity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Severity::Info => write!(f, "Info"),
Severity::Warning => write!(f, "Warning"),
Severity::Error => write!(f, "Error"),
Severity::Critical => write!(f, "Critical"),
}
}
}
pub trait Analyzer: Send + Sync {
fn name(&self) -> &str;
fn analyze(&self, snapshot: &MemorySnapshot) -> AnalysisResult;
}
#[cfg(test)]
mod tests {
use super::*;
struct DummyAnalyzer;
impl Analyzer for DummyAnalyzer {
fn name(&self) -> &str {
"dummy"
}
fn analyze(&self, snapshot: &MemorySnapshot) -> AnalysisResult {
AnalysisResult {
analyzer_name: "dummy".to_string(),
issue_count: snapshot.active_count(),
severity: Severity::Info,
description: "Dummy analysis".to_string(),
findings: vec![],
}
}
}
#[test]
fn test_analyzer_trait() {
let analyzer = DummyAnalyzer;
assert_eq!(analyzer.name(), "dummy");
let snapshot = MemorySnapshot::new();
let result = analyzer.analyze(&snapshot);
assert_eq!(result.analyzer_name, "dummy");
}
}