<commit_before>extern crate regex;

mod filters;

use errors::*;
use linter::filters::*;

#[derive(Debug, RustcEncodable)]
pub struct LinterWarning {
    pub message: &'static str,
    pub start: usize,
    pub end: usize,
}

pub struct Linter {
    locale: String,
}

impl Linter {
    pub fn new(locale: String) -> Result<Linter, LughError> {
        let linter = Linter { locale: locale };

        Ok(linter)
    }

    pub fn check(&self, text: &str) -> Result<(), Vec<LinterWarning>> {
        let mut warnings = Vec::<LinterWarning>::new();

        let filters: Vec<Box<LinterFilter>> = vec![
            Box::new(CurlyApostropheFilter {}),
            Box::new(EllipsisSymbolFilter {}),
            Box::new(NoSpaceBeforeCommaFilter {}),
            Box::new(SpaceBeforeDoublePonctuationFilter {}),
        ];

        let active_filters = filters
            .into_iter()
            .filter( |filter| filter.locales().is_empty() ||
                filter.locales().contains(&self.locale.as_str()) )
            .collect::<Vec<Box<LinterFilter>>>();

        for filter in &active_filters {
            let result = filter.check(text);

            if result.is_err() {
                warnings.append(&mut result.err().unwrap());
            }
        }

        if warnings.is_empty() {
            Ok(())
        } else {
            Err(warnings)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_linter_with_two_warnings() {
        let linter = Linter::new("en".to_string()).unwrap();

        let result = linter.check("It's me...");

        assert!(result.is_err());<commit_msg>Move filters into functions in Linter<commit_after>extern crate regex;

mod filters;

use errors::*;
use linter::filters::*;

#[derive(Debug, RustcEncodable)]
pub struct LinterWarning {
    pub message: &'static str,
    pub start: usize,
    pub end: usize,
}

pub struct Linter {
    locale: String,
}

impl Linter {
    pub fn new(locale: String) -> Result<Linter, LughError> {
        let linter = Linter { locale: locale };

        Ok(linter)
    }

    pub fn check(&self, text: &str) -> Result<(), Vec<LinterWarning>> {
        let mut warnings = Vec::<LinterWarning>::new();

        for filter in &self.active_filters(self.locale.as_str()) {
            let result = filter.check(text);

            if result.is_err() {
                warnings.append(&mut result.err().unwrap());
            }
        }

        if warnings.is_empty() {
            Ok(())
        } else {
            Err(warnings)
        }
    }

    fn active_filters(&self, locale: &str) -> Vec<Box<LinterFilter>> {
        self.filters()
            .into_iter()
            .filter(|filter| filter.locales().is_empty() || filter.locales().contains(&locale))
            .collect()
    }

    fn filters(&self) -> Vec<Box<LinterFilter>> {
        vec![
            Box::new(CurlyApostropheFilter {}),
            Box::new(EllipsisSymbolFilter {}),
            Box::new(NoSpaceBeforeCommaFilter {}),
            Box::new(SpaceBeforeDoublePonctuationFilter {}),
        ]
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_linter_with_two_warnings() {
        let linter = Linter::new("en".to_string()).unwrap();

        let result = linter.check("It's me...");

        assert!(result.is_err());
{'fraction_non_alphanumeric': 0.1502994011976048, 'fraction_numerical': 0.0, 'mean_word_length': 2.2155919153031762, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7203037', 'n_tokens_mistral': 1041, 'n_tokens_neox': 1028, 'n_words': 212}