lint 0.1.3

A versatile linting tool with CLI, MCP, and library interfaces
Documentation
use crate::output::{LintMessage, Severity};
use crate::rules::Rule;
use regex::Regex;
use serde::Deserialize;
use std::path::Path;

#[derive(Debug, Clone, Deserialize)]
pub struct CustomRuleDefinition {
    pub name: String,
    pub pattern: String,
    pub message: String,
    pub severity: String,
    pub suggestion: Option<String>,
    pub extensions: Option<Vec<String>>,
}

#[derive(Debug, Clone)]
pub struct CustomRule {
    definition: CustomRuleDefinition,
    regex: Regex,
}

impl CustomRule {
    pub fn from_definition(def: CustomRuleDefinition) -> Result<Self, regex::Error> {
        let regex = Regex::new(&def.pattern)?;
        Ok(Self {
            definition: def,
            regex,
        })
    }
}

impl Rule for CustomRule {
    fn name(&self) -> &str {
        &self.definition.name
    }

    fn category(&self) -> &str {
        "custom"
    }

    fn check(&self, content: &str, file_path: &Path) -> Vec<LintMessage> {
        if let Some(ref extensions) = self.definition.extensions {
            let ext_matches = file_path.extension().is_some_and(|ext| {
                let ext_str = ext.to_string_lossy();
                extensions.iter().any(|e| e == ext_str.as_ref())
            });
            if !ext_matches {
                return Vec::new();
            }
        }

        let mut messages = Vec::new();
        let severity = match self.definition.severity.as_str() {
            "Error" => Severity::Error,
            "Warning" => Severity::Warning,
            _ => Severity::Info,
        };

        for (line_num, line) in content.lines().enumerate() {
            if self.regex.is_match(line) {
                messages.push(LintMessage::new(
                    line_num + 1,
                    0,
                    severity,
                    self.definition.message.clone(),
                    self.definition.name.clone(),
                    self.definition.suggestion.clone(),
                ));
            }
        }

        messages
    }
}