use masterror::AppResult;
use syn::File;
#[derive(Debug, Clone, PartialEq)]
pub enum Fix {
None,
#[allow(dead_code)]
Simple(String),
WithImport {
import: String,
pattern: String,
replacement: String
}
}
impl Fix {
#[inline]
pub fn is_available(&self) -> bool {
!matches!(self, Fix::None)
}
#[inline]
pub fn as_simple(&self) -> Option<&str> {
match self {
Fix::Simple(s) => Some(s.as_str()),
_ => None
}
}
#[inline]
pub fn as_import(&self) -> Option<(&str, &str, &str)> {
match self {
Fix::WithImport {
import,
pattern,
replacement
} => Some((import.as_str(), pattern.as_str(), replacement.as_str())),
_ => None
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Issue {
pub line: usize,
pub column: usize,
pub message: String,
pub fix: Fix
}
#[derive(Debug, Default)]
pub struct AnalysisResult {
pub issues: Vec<Issue>,
pub fixable_count: usize
}
pub trait Analyzer {
fn name(&self) -> &'static str;
fn analyze(&self, ast: &File, content: &str) -> AppResult<AnalysisResult>;
fn fix(&self, ast: &mut File) -> AppResult<usize>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fix_none() {
let fix = Fix::None;
assert!(!fix.is_available());
assert!(fix.as_simple().is_none());
assert!(fix.as_import().is_none());
}
#[test]
fn test_fix_simple() {
let fix = Fix::Simple("replacement".to_string());
assert!(fix.is_available());
assert_eq!(fix.as_simple(), Some("replacement"));
assert!(fix.as_import().is_none());
}
#[test]
fn test_fix_with_import() {
let fix = Fix::WithImport {
import: "use std::fs::read;".to_string(),
pattern: "std::fs::read".to_string(),
replacement: "read".to_string()
};
assert!(fix.is_available());
assert!(fix.as_simple().is_none());
assert_eq!(
fix.as_import(),
Some(("use std::fs::read;", "std::fs::read", "read"))
);
}
#[test]
fn test_issue_creation() {
let issue = Issue {
line: 42,
column: 10,
message: "Test issue".to_string(),
fix: Fix::Simple("Fix suggestion".to_string())
};
assert_eq!(issue.line, 42);
assert_eq!(issue.column, 10);
assert!(issue.fix.is_available());
}
#[test]
fn test_analysis_result_default() {
let result = AnalysisResult::default();
assert_eq!(result.issues.len(), 0);
assert_eq!(result.fixable_count, 0);
}
}