sqruff_lib/rules/layout/
lt01.rs

1use ahash::AHashMap;
2
3use crate::core::config::Value;
4use crate::core::rules::base::{Erased, ErasedRule, LintResult, Rule, RuleGroups};
5use crate::core::rules::context::RuleContext;
6use crate::core::rules::crawlers::{Crawler, RootOnlyCrawler};
7use crate::utils::reflow::sequence::{Filter, ReflowSequence};
8
9#[derive(Default, Debug, Clone)]
10pub struct RuleLT01;
11
12impl Rule for RuleLT01 {
13    fn load_from_config(&self, _config: &AHashMap<String, Value>) -> Result<ErasedRule, String> {
14        Ok(RuleLT01.erased())
15    }
16    fn name(&self) -> &'static str {
17        "layout.spacing"
18    }
19
20    fn description(&self) -> &'static str {
21        "Inappropriate Spacing."
22    }
23
24    fn long_description(&self) -> &'static str {
25        r#"
26**Anti-pattern**
27
28In this example, spacing is all over the place and is represented by `•`.
29
30```sql
31SELECT
32    a,        b(c) as d••
33FROM foo••••
34JOIN bar USING(a)
35```
36
37**Best practice**
38
39- Unless an indent or preceding a comment, whitespace should be a single space.
40- There should also be no trailing whitespace at the ends of lines.
41- There should be a space after USING so that it’s not confused for a function.
42
43```sql
44SELECT
45    a, b(c) as d
46FROM foo
47JOIN bar USING (a)
48```
49"#
50    }
51
52    fn groups(&self) -> &'static [RuleGroups] {
53        &[RuleGroups::All, RuleGroups::Core, RuleGroups::Layout]
54    }
55
56    fn eval(&self, context: &RuleContext) -> Vec<LintResult> {
57        let sequence = ReflowSequence::from_root(context.segment.clone(), context.config);
58        sequence
59            .respace(context.tables, false, Filter::All)
60            .results()
61    }
62
63    fn is_fix_compatible(&self) -> bool {
64        true
65    }
66
67    fn crawl_behaviour(&self) -> Crawler {
68        RootOnlyCrawler.into()
69    }
70}