Skip to main content

code_baseline/cli/
toml_config.rs

1use crate::config::{RuleConfig, Severity};
2use serde::Deserialize;
3
4/// Top-level TOML config file structure.
5#[derive(Debug, Deserialize)]
6pub struct TomlConfig {
7    pub baseline: BaselineSection,
8    #[serde(default)]
9    pub rule: Vec<TomlRule>,
10}
11
12/// The `[baseline]` section.
13#[derive(Debug, Deserialize)]
14pub struct BaselineSection {
15    #[allow(dead_code)]
16    pub name: Option<String>,
17    #[serde(default)]
18    pub include: Vec<String>,
19    #[serde(default)]
20    pub exclude: Vec<String>,
21    #[serde(default)]
22    pub extends: Vec<String>,
23    /// Paths to plugin TOML files containing additional rules
24    #[serde(default)]
25    pub plugins: Vec<String>,
26}
27
28/// A single `[[rule]]` entry.
29#[derive(Debug, Clone, Deserialize)]
30pub struct TomlRule {
31    pub id: String,
32    #[serde(rename = "type")]
33    pub rule_type: String,
34    #[serde(default = "default_severity")]
35    pub severity: String,
36    pub glob: Option<String>,
37    #[serde(default)]
38    pub message: String,
39    pub suggest: Option<String>,
40    #[serde(default)]
41    pub allowed_classes: Vec<String>,
42    #[serde(default)]
43    pub token_map: Vec<String>,
44    pub pattern: Option<String>,
45    pub max_count: Option<usize>,
46    #[serde(default)]
47    pub packages: Vec<String>,
48    #[serde(default)]
49    pub regex: bool,
50    pub manifest: Option<String>,
51    #[serde(default)]
52    pub exclude_glob: Vec<String>,
53    pub file_contains: Option<String>,
54    pub file_not_contains: Option<String>,
55    #[serde(default)]
56    pub required_files: Vec<String>,
57    #[serde(default)]
58    pub forbidden_files: Vec<String>,
59    pub condition_pattern: Option<String>,
60}
61
62fn default_severity() -> String {
63    "warning".into()
64}
65
66impl Default for TomlRule {
67    fn default() -> Self {
68        Self {
69            id: String::new(),
70            rule_type: String::new(),
71            severity: default_severity(),
72            glob: None,
73            message: String::new(),
74            suggest: None,
75            allowed_classes: Vec::new(),
76            token_map: Vec::new(),
77            pattern: None,
78            max_count: None,
79            packages: Vec::new(),
80            regex: false,
81            manifest: None,
82            exclude_glob: Vec::new(),
83            file_contains: None,
84            file_not_contains: None,
85            required_files: Vec::new(),
86            forbidden_files: Vec::new(),
87            condition_pattern: None,
88        }
89    }
90}
91
92impl TomlRule {
93    /// Convert to the core `RuleConfig` type.
94    pub fn to_rule_config(&self) -> RuleConfig {
95        let severity = match self.severity.to_lowercase().as_str() {
96            "error" => Severity::Error,
97            _ => Severity::Warning,
98        };
99
100        RuleConfig {
101            id: self.id.clone(),
102            severity,
103            message: self.message.clone(),
104            suggest: self.suggest.clone(),
105            glob: self.glob.clone(),
106            allowed_classes: self.allowed_classes.clone(),
107            token_map: self.token_map.clone(),
108            pattern: self.pattern.clone(),
109            max_count: self.max_count,
110            packages: self.packages.clone(),
111            regex: self.regex,
112            manifest: self.manifest.clone(),
113            exclude_glob: self.exclude_glob.clone(),
114            file_contains: self.file_contains.clone(),
115            file_not_contains: self.file_not_contains.clone(),
116            required_files: self.required_files.clone(),
117            forbidden_files: self.forbidden_files.clone(),
118            condition_pattern: self.condition_pattern.clone(),
119        }
120    }
121}