swc_css_lints/rules/
color_hex_alpha.rs

1use serde::{Deserialize, Serialize};
2use swc_css_ast::*;
3use swc_css_visit::{Visit, VisitWith};
4
5use crate::rule::{visitor_rule, LintRule, LintRuleContext};
6
7pub type ColorHexAlphaConfig = Option<Preference>;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub enum Preference {
12    Always,
13    Never,
14}
15
16impl Default for Preference {
17    fn default() -> Self {
18        Self::Always
19    }
20}
21
22pub fn color_hex_alpha(ctx: LintRuleContext<ColorHexAlphaConfig>) -> Box<dyn LintRule> {
23    let preference = ctx.config().clone().unwrap_or_default();
24    visitor_rule(ctx.reaction(), ColorHexAlpha { ctx, preference })
25}
26
27#[derive(Debug, Default)]
28struct ColorHexAlpha {
29    ctx: LintRuleContext<ColorHexAlphaConfig>,
30    preference: Preference,
31}
32
33impl Visit for ColorHexAlpha {
34    fn visit_hex_color(&mut self, hex_color: &HexColor) {
35        let length = hex_color.value.len();
36        match self.preference {
37            Preference::Always if length == 3 || length == 6 => {
38                self.ctx.report(
39                    hex_color,
40                    format!("Expected alpha channel in '#{}'.", hex_color.value),
41                );
42            }
43            Preference::Never if length == 4 || length == 8 => {
44                self.ctx.report(
45                    hex_color,
46                    format!("Unexpected alpha channel in '#{}'.", hex_color.value),
47                );
48            }
49            _ => {}
50        }
51
52        hex_color.visit_children_with(self);
53    }
54}