feat: work in progress on #954

This commit is contained in:
hippietrail 2025-12-20 15:41:24 +08:00
parent 5e5a0a473a
commit a8016cde08
3 changed files with 111 additions and 0 deletions

View file

@ -0,0 +1,70 @@
use crate::{
expr::{Expr, SequenceExpr},
linting::{ExprLinter, expr_linter::Chunk, debug::format_lint_match},
Token, Lint
};
pub struct Damages {
expr: Box<dyn Expr>,
}
impl Default for Damages {
fn default() -> Self {
Self {
expr: Box::new(SequenceExpr::word_set(&["damages", "damage"])),
}
}
}
impl ExprLinter for Damages {
type Unit = Chunk;
fn expr(&self) -> &dyn Expr {
self.expr.as_ref()
}
fn match_to_lint_with_context(&self, toks: &[Token], src: &[char], ctx: Option<(&[Token], &[Token])>) -> Option<Lint> {
eprintln!("🩵 {}", format_lint_match(toks, ctx, src));
None
}
fn description(&self) -> &str {
"Checks for plural `damages` not in the context of a court case."
}
}
#[cfg(test)]
mod tests {
// Examples of the error from GitHub:
// Flow networks robust against damages are simple model networks described in a series of publications by Kaluza et al.
// POC to select vehicle damages on a car and mark the severity - sudheeshcm/vehicle-damage-selector.
// This is a web application that detects damages on mangoes using a TensorFlow model with Django as the frontend framework
// Detecting different types of damages of roads like cracks and potholes for the given image/video of the road.
// Examples from GitHub where it seems to be used correctly in regard to financial compensation:
// Code used for calculating damages in lost chance cases.
// Where the dispute involves a claim for damages in respect of a motor accident for cost of rental of a replacement vehicle
// Under this section, the Commercial Contributor would have to
// defend claims against the other Contributors related to those
// performance claims and warranties, and if a court requires any other
// Contributor to pay any damages as a result, the Commercial Contributor
// must pay those damages.
// Examples from GitHub where it's not an error but a verb:
// Profiles pb's and damages them when their runtime goes over a set value - sirhamsteralot/HaE-PBLimiter.
// Opening Wayland-native terminal damages Firefox
// Open File Requester damages underlaying windows when moved
// Examples from GitHub that are too hard to call - maybe they are talking about financial compensation?
// The goal is to estimate the damages of each link in the Graph object using the Damages result (estimating the damages for each segment of a Network).
// This repository contains code to conduct statistical inference in cartel damages estimation. It will be updated to include a Stata .do file which approximates the standard error of total damages from a fixed effects panel data model, using the delta method.
// Financial damages caused by received errors $$$$
// It would be useful to be able to see asset-level damages after running FDA 2.0.
}

View file

@ -48,6 +48,7 @@ use super::correct_number_suffix::CorrectNumberSuffix;
use super::criteria_phenomena::CriteriaPhenomena;
use super::cure_for::CureFor;
use super::currency_placement::CurrencyPlacement;
use super::damages::Damages;
use super::despite_of::DespiteOf;
use super::didnt::Didnt;
use super::discourse_markers::DiscourseMarkers;
@ -523,6 +524,7 @@ impl LintGroup {
insert_expr_rule!(CriteriaPhenomena, true);
insert_expr_rule!(CureFor, true);
insert_struct_rule!(CurrencyPlacement, true);
insert_expr_rule!(Damages, true);
insert_expr_rule!(Dashes, true);
insert_expr_rule!(DespiteOf, true);
insert_expr_rule!(Didnt, true);

View file

@ -41,6 +41,7 @@ mod correct_number_suffix;
mod criteria_phenomena;
mod cure_for;
mod currency_placement;
mod damages;
mod dashes;
mod despite_of;
mod determiner_without_noun;
@ -256,6 +257,44 @@ where
}
}
pub mod debug {
use crate::{Token, token_string_ext::TokenStringExt};
/// Formats a lint match with surrounding context for debug output.
///
/// The function takes the same `matched_tokens` and `source`, and `context` parameters
/// passed to `[match_to_lint_with_context]`.
///
/// # Arguments
/// * `log` - `matched_tokens`
/// * `ctx` - `context`, or `None` if calling from `[match_to_lint]`
/// * `src` - `source` from `[match_to_lint]` / `[match_to_lint_with_context]`
///
/// # Returns
/// A string with ANSI escape codes where:
/// - Context tokens are dimmed before and after the matched tokens in normal weight.
/// - Markup and formatting text hidden in whitespace tokens is filtered out.
pub fn format_lint_match(
log: &[Token],
ctx: Option<(&[Token], &[Token])>,
src: &[char],
) -> String {
if let Some((pro, epi)) = ctx {
let [pro, log, epi] = [pro, log, epi].map(|tt| {
tt.iter()
.filter(|t| !t.kind.is_whitespace() && !t.kind.is_newline())
.map(|t| t.span.get_content_string(src))
.collect::<Vec<_>>()
.join(" ")
});
format!("\x1b[2m{}\x1b[0m {} \x1b[2m{}\x1b[0m", pro, log, epi,)
} else {
log.span()
.map_or_else(String::new, |span| span.get_content_string(src))
}
}
}
#[cfg(test)]
pub mod tests {
use crate::parsers::Markdown;