use crate::linting::expr_linter::Chunk;
use crate::{
Token,
expr::{AnchorStart, Expr, SequenceExpr},
linting::{ExprLinter, Lint, LintKind, Suggestion},
};
pub struct HelloGreeting {
expr: SequenceExpr,
}
impl Default for HelloGreeting {
fn default() -> Self {
let expr = SequenceExpr::with(AnchorStart)
.then_optional(SequenceExpr::default().t_ws())
.then_optional(
SequenceExpr::default()
.then_quote()
.then_optional(SequenceExpr::default().t_ws()),
)
.t_aco("halo");
Self { expr }
}
}
impl ExprLinter for HelloGreeting {
type Unit = Chunk;
fn expr(&self) -> &dyn Expr {
&self.expr
}
fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Option<Lint> {
let word = matched_tokens.iter().find(|tok| tok.kind.is_word())?;
let span = word.span;
let original = span.get_content(source);
Some(Lint {
span,
lint_kind: LintKind::WordChoice,
suggestions: vec![Suggestion::replace_with_match_case(
"hello".chars().collect(),
original,
)],
message: "Prefer `hello` as a greeting; `halo` refers to the optical effect."
.to_owned(),
priority: 31,
})
}
fn description(&self) -> &'static str {
"Encourages greeting someone with `hello` instead of the homophone `halo`."
}
}
#[cfg(test)]
mod tests {
use super::HelloGreeting;
use crate::linting::tests::{assert_lint_count, assert_suggestion_result};
#[test]
fn corrects_basic_greeting() {
assert_suggestion_result("Halo John!", HelloGreeting::default(), "Hello John!");
}
#[test]
fn corrects_with_comma() {
assert_suggestion_result("Halo, Jane.", HelloGreeting::default(), "Hello, Jane.");
}
#[test]
fn corrects_with_world() {
assert_suggestion_result("Halo world!", HelloGreeting::default(), "Hello world!");
}
#[test]
fn corrects_without_punctuation() {
assert_suggestion_result(
"Halo there friend.",
HelloGreeting::default(),
"Hello there friend.",
);
}
#[test]
fn corrects_single_word_sentence() {
assert_suggestion_result("Halo!", HelloGreeting::default(), "Hello!");
}
#[test]
fn corrects_question() {
assert_suggestion_result("Halo?", HelloGreeting::default(), "Hello?");
}
#[test]
fn corrects_uppercase() {
assert_suggestion_result("HALO!", HelloGreeting::default(), "HELLO!");
}
#[test]
fn no_lint_for_optical_term() {
assert_lint_count(
"The halo around the moon glowed softly.",
HelloGreeting::default(),
0,
);
}
#[test]
fn no_lint_mid_sentence() {
assert_lint_count(
"They shouted hello, not Halo, during rehearsal.",
HelloGreeting::default(),
0,
);
}
#[test]
fn corrects_in_quotes() {
assert_suggestion_result(
"\"Halo John!\"",
HelloGreeting::default(),
"\"Hello John!\"",
);
}
}