1use std::{collections::HashMap, path::Path};
2
3use serde::{Deserialize, Serialize};
4
5use crate::lint::Severity;
6
7#[derive(Debug, Clone, Deserialize, Serialize, Default)]
8pub struct Config {
9 #[serde(default)]
10 pub general: GeneralConfig,
11
12 #[serde(default)]
13 pub rules: HashMap<String, RuleSeverity>,
14
15 #[serde(default)]
16 pub style: StyleConfig,
17
18 #[serde(default)]
19 pub exclude: ExcludeConfig,
20
21 #[serde(default)]
22 pub fix: FixConfig,
23}
24
25#[derive(Debug, Clone, Deserialize, Serialize, Default)]
26pub struct GeneralConfig {
27 pub max_severity: RuleSeverity,
28}
29
30#[derive(Debug, Clone, Copy, Deserialize, Serialize, Default)]
31#[serde(rename_all = "lowercase")]
32pub enum RuleSeverity {
33 #[default]
34 Error,
35 Warning,
36 Info,
37 Off,
38}
39
40impl From<RuleSeverity> for Option<Severity> {
41 fn from(rule_sev: RuleSeverity) -> Self {
42 match rule_sev {
43 RuleSeverity::Error => Some(Severity::Error),
44 RuleSeverity::Warning => Some(Severity::Warning),
45 RuleSeverity::Info => Some(Severity::Info),
46 RuleSeverity::Off => None,
47 }
48 }
49}
50
51#[derive(Debug, Clone, Deserialize, Serialize, Default)]
52pub struct StyleConfig {
53 #[serde(default = "StyleConfig::default_line_length")]
54 pub line_length: usize,
55
56 #[serde(default = "StyleConfig::default_indent_spaces")]
57 pub indent_spaces: usize,
58}
59
60impl StyleConfig {
61 const fn default_line_length() -> usize {
62 100
63 }
64
65 const fn default_indent_spaces() -> usize {
66 4
67 }
68}
69
70#[derive(Debug, Clone, Deserialize, Serialize, Default)]
71pub struct ExcludeConfig {
72 #[serde(default)]
73 pub patterns: Vec<String>,
74}
75
76#[derive(Debug, Clone, Deserialize, Serialize, Default)]
77pub struct FixConfig {
78 pub enabled: bool,
79
80 pub safe_only: bool,
81}
82
83impl Config {
84 pub fn load_from_file(path: &Path) -> Result<Self, crate::LintError> {
91 let content = std::fs::read_to_string(path)?;
92 Ok(toml::from_str(&content)?)
93 }
94
95 pub fn rule_severity(&self, rule_id: &str) -> Option<Severity> {
96 self.rules.get(rule_id).copied().and_then(Into::into)
97 }
98}