use itertools::Itertools;
use crate::expr::{Expr, FirstMatchOf, WordExprGroup};
use crate::thesaurus_helper;
use crate::{Token, TokenStringExt};
use super::{ExprLinter, Lint, LintKind};
use crate::linting::expr_linter::Chunk;
pub struct BoringWords {
expr: WordExprGroup<FirstMatchOf>,
}
impl Default for BoringWords {
fn default() -> Self {
let mut expr = WordExprGroup::default();
expr.add_word("very");
expr.add_word("interesting");
expr.add_word("several");
expr.add_word("most");
expr.add_word("many");
Self { expr }
}
}
impl ExprLinter for BoringWords {
type Unit = Chunk;
fn expr(&self) -> &dyn Expr {
&self.expr
}
fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Option<Lint> {
let matched_word = matched_tokens.span()?.get_content_string(source);
Some(Lint {
span: matched_tokens.span()?,
lint_kind: LintKind::Enhancement,
suggestions: thesaurus_helper::get_synonym_replacement_suggestions(
&matched_word,
&matched_tokens[0].kind,
)
.take(5)
.collect_vec(),
message: format!(
"“{matched_word}” is a boring word. Try something a little more exotic."
),
priority: 127,
})
}
fn description(&self) -> &'static str {
"This rule looks for particularly boring or overused words. Using varied language is an easy way to keep a reader's attention."
}
}