use crate::problem::{LintLevel, LintProblem};
use crate::rules::{LintContext, Rule, RuleLevel};
#[derive(Debug)]
pub struct LineLengthRule {
pub max: usize,
}
impl LineLengthRule {
pub fn new() -> Self {
Self { max: 80 }
}
pub fn with_max(max: usize) -> Self {
Self { max }
}
}
impl Default for LineLengthRule {
fn default() -> Self {
Self::new()
}
}
impl Rule for LineLengthRule {
fn name(&self) -> &'static str {
"line-length"
}
fn check(&self, context: &LintContext) -> Vec<LintProblem> {
let mut problems = Vec::new();
for (line_idx, line) in context.lines.iter().enumerate() {
let line_length = line.len();
if line_length > self.max {
problems.push(LintProblem::new(
line_idx + 1, self.max + 1, format!(
"line too long ({} > {} characters)",
line_length, self.max
),
self.name(),
LintLevel::Error,
));
}
}
problems
}
fn default_level(&self) -> RuleLevel {
RuleLevel::Error
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_line_within_limit() {
let yaml = "key: value\n";
let context = LintContext::new(yaml.to_string());
let rule = LineLengthRule::new();
let problems = rule.check(&context);
assert!(problems.is_empty());
}
#[test]
fn test_line_exceeds_limit() {
let long_line = "key: ".to_string() + &"x".repeat(77); let yaml = format!("{}\n", long_line);
let context = LintContext::new(yaml);
let rule = LineLengthRule::new();
let problems = rule.check(&context);
assert_eq!(problems.len(), 1);
assert_eq!(problems[0].line, 1);
assert_eq!(problems[0].column, 81); assert!(problems[0].message.contains("81 > 80"));
}
#[test]
fn test_custom_max_length() {
let yaml = "key: ".to_string() + &"x".repeat(100); let context = LintContext::new(yaml);
let rule = LineLengthRule::with_max(120);
let problems = rule.check(&context);
assert!(problems.is_empty()); }
#[test]
fn test_multiple_long_lines() {
let line1 = "key1: ".to_string() + &"x".repeat(81); let line2 = "key2: value"; let line3 = "key3: ".to_string() + &"x".repeat(90); let yaml = format!("{}\n{}\n{}\n", line1, line2, line3);
let context = LintContext::new(yaml);
let rule = LineLengthRule::new();
let problems = rule.check(&context);
assert_eq!(problems.len(), 2);
assert_eq!(problems[0].line, 1);
assert_eq!(problems[1].line, 3);
}
#[test]
fn test_exactly_at_limit() {
let yaml = "x".repeat(80) + "\n";
let context = LintContext::new(yaml);
let rule = LineLengthRule::new();
let problems = rule.check(&context);
assert!(problems.is_empty());
}
#[test]
fn test_empty_line() {
let yaml = "\n";
let context = LintContext::new(yaml.to_string());
let rule = LineLengthRule::new();
let problems = rule.check(&context);
assert!(problems.is_empty());
}
}