rigsql_rules/layout/
lt06.rs1use rigsql_core::SegmentType;
2
3use crate::rule::{CrawlType, Rule, RuleContext, RuleGroup};
4use crate::violation::{LintViolation, SourceEdit};
5
6#[derive(Debug, Default)]
11pub struct RuleLT06;
12
13impl Rule for RuleLT06 {
14 fn code(&self) -> &'static str {
15 "LT06"
16 }
17 fn name(&self) -> &'static str {
18 "layout.function_paren"
19 }
20 fn description(&self) -> &'static str {
21 "Function name not followed immediately by parenthesis."
22 }
23 fn explanation(&self) -> &'static str {
24 "In SQL, function calls should have the opening parenthesis immediately after \
25 the function name with no intervening whitespace. For example, write COUNT(*) \
26 rather than COUNT (*)."
27 }
28 fn groups(&self) -> &[RuleGroup] {
29 &[RuleGroup::Layout]
30 }
31 fn is_fixable(&self) -> bool {
32 true
33 }
34
35 fn crawl_type(&self) -> CrawlType {
36 CrawlType::Segment(vec![SegmentType::FunctionCall])
37 }
38
39 fn eval(&self, ctx: &RuleContext) -> Vec<LintViolation> {
40 let children = ctx.segment.children();
41
42 let mut name_idx = None;
44 for (i, child) in children.iter().enumerate() {
45 if !child.segment_type().is_trivia() {
46 name_idx = Some(i);
47 break;
48 }
49 }
50
51 let Some(name_idx) = name_idx else {
52 return vec![];
53 };
54
55 let mut whitespace_spans = Vec::new();
57 let mut found_lparen = false;
58
59 for child in &children[name_idx + 1..] {
60 let st = child.segment_type();
61 if st == SegmentType::Whitespace || st == SegmentType::Newline {
62 whitespace_spans.push(child.span());
63 } else if st == SegmentType::LParen || st == SegmentType::FunctionArgs {
64 found_lparen = true;
65 break;
66 } else {
67 break;
69 }
70 }
71
72 if !found_lparen || whitespace_spans.is_empty() {
73 return vec![];
74 }
75
76 let fixes: Vec<SourceEdit> = whitespace_spans
77 .iter()
78 .map(|span| SourceEdit::delete(*span))
79 .collect();
80
81 let first_ws = whitespace_spans[0];
82 vec![LintViolation::with_fix(
83 self.code(),
84 "No whitespace allowed between function name and parenthesis.",
85 first_ws,
86 fixes,
87 )]
88 }
89}