use crate::{
Lint, Token, TokenStringExt,
expr::{Expr, SequenceExpr},
linting::{ExprLinter, LintKind, Suggestion, expr_linter::Chunk},
};
pub struct LookDownOnesNose {
expr: SequenceExpr,
}
impl Default for LookDownOnesNose {
fn default() -> Self {
Self {
expr: SequenceExpr::word_set(&["look", "looked", "looking", "looks"])
.t_ws()
.then_possessive_determiner()
.t_ws()
.then_word_set(&["nose", "noses"])
.t_ws()
.t_aco("down"),
}
}
}
impl ExprLinter for LookDownOnesNose {
type Unit = Chunk;
fn description(&self) -> &str {
"Corrects `look one's nose down` to `look down one's nose`"
}
fn match_to_lint(&self, toks: &[Token], src: &[char]) -> Option<Lint> {
let (looktok, prontok, nosetok) = (toks.first()?, toks.get(2)?, toks.get(4)?);
let (lookspan, pronspan, nosespan) = (looktok.span, prontok.span, nosetok.span);
let (lookstr, pronstr, nosestr) = (
lookspan.get_content_string(src),
pronspan.get_content_string(src),
nosespan.get_content_string(src),
);
Some(Lint {
lint_kind: LintKind::Usage,
span: toks.span()?,
suggestions: vec![Suggestion::replace_with_match_case(
format!("{lookstr} down {pronstr} {nosestr}")
.chars()
.collect(),
toks.span()?.get_content(src),
)],
message: "The correct idiom is `look down one's nose`.".to_string(),
..Default::default()
})
}
fn expr(&self) -> &dyn Expr {
&self.expr
}
}
#[cfg(test)]
mod tests {
use super::LookDownOnesNose;
use crate::linting::tests::assert_suggestion_result;
#[test]
fn look_his_nose() {
assert_suggestion_result(
"He seemed to look his nose down upon everything",
LookDownOnesNose::default(),
"He seemed to look down his nose upon everything",
);
}
#[test]
fn look_my_nose() {
assert_suggestion_result(
"I'm the last one to look my nose down at what people do from a moral perspective.",
LookDownOnesNose::default(),
"I'm the last one to look down my nose at what people do from a moral perspective.",
);
}
#[test]
fn look_their_nose() {
assert_suggestion_result(
"I hate how humans look their nose down on certain animals",
LookDownOnesNose::default(),
"I hate how humans look down their nose on certain animals",
);
}
#[test]
fn look_their_noses() {
assert_suggestion_result(
"Yet many look their noses down at the right as if it were a used Kleenex.",
LookDownOnesNose::default(),
"Yet many look down their noses at the right as if it were a used Kleenex.",
);
}
#[test]
fn look_your_nose() {
assert_suggestion_result(
"You look your nose down on me like I am only a breathing object",
LookDownOnesNose::default(),
"You look down your nose on me like I am only a breathing object",
);
}
#[test]
fn looking_her_nose() {
assert_suggestion_result(
"The long nose definitely helps give the feel of her looking her nose down on others",
LookDownOnesNose::default(),
"The long nose definitely helps give the feel of her looking down her nose on others",
);
}
#[test]
fn looking_his_nose() {
assert_suggestion_result(
"literally looking his nose down at the commoners",
LookDownOnesNose::default(),
"literally looking down his nose at the commoners",
);
}
#[test]
fn looking_their_noses() {
assert_suggestion_result(
"It makes no sense that the princesses are looking their noses down on her",
LookDownOnesNose::default(),
"It makes no sense that the princesses are looking down their noses on her",
);
}
#[test]
fn looking_your_nose() {
assert_suggestion_result(
"Whatever you do, don’t fall into the trap of looking your nose down at the customer.",
LookDownOnesNose::default(),
"Whatever you do, don’t fall into the trap of looking down your nose at the customer.",
);
}
#[test]
fn looks_her_nose() {
assert_suggestion_result(
"Daenerys looks her nose down at them.",
LookDownOnesNose::default(),
"Daenerys looks down her nose at them.",
);
}
#[test]
fn looks_his_nose() {
assert_suggestion_result(
"He probably looks his nose down on Wraith, who don't eat inbred humans.",
LookDownOnesNose::default(),
"He probably looks down his nose on Wraith, who don't eat inbred humans.",
);
}
#[test]
fn looks_their_nose() {
assert_suggestion_result(
"Your friend looks their nose down at them and wants to unfriend them based on how little money they have.",
LookDownOnesNose::default(),
"Your friend looks down their nose at them and wants to unfriend them based on how little money they have.",
);
}
}