pedant_core/check_config/
gate.rs1use std::collections::BTreeMap;
2
3use serde::Deserialize;
4
5#[derive(Debug)]
7pub enum GateRuleOverride {
8 Disabled,
10 Severity(crate::gate::GateSeverity),
12}
13
14#[derive(Debug)]
19pub struct GateConfig {
20 pub enabled: bool,
22 pub overrides: BTreeMap<Box<str>, GateRuleOverride>,
24}
25
26impl Default for GateConfig {
27 fn default() -> Self {
28 Self {
29 enabled: true,
30 overrides: BTreeMap::new(),
31 }
32 }
33}
34
35impl<'de> Deserialize<'de> for GateConfig {
36 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37 where
38 D: serde::Deserializer<'de>,
39 {
40 use serde::de::Error;
41
42 #[derive(Deserialize)]
43 #[serde(untagged)]
44 enum GateTomlValue {
45 Bool(bool),
46 String(String),
47 }
48
49 let raw: BTreeMap<Box<str>, GateTomlValue> = BTreeMap::deserialize(deserializer)?;
50 let mut enabled = true;
51 let mut overrides = BTreeMap::new();
52
53 for (key, value) in raw {
54 match (&*key, value) {
55 ("enabled", GateTomlValue::Bool(b)) => enabled = b,
56 ("enabled", GateTomlValue::String(_)) => {
57 return Err(D::Error::custom("'enabled' must be a boolean"));
58 }
59 (_, _) if !is_known_gate_rule(&key) => {
60 return Err(D::Error::custom(format!("unknown gate rule '{key}'")));
61 }
62 (_, GateTomlValue::Bool(false)) => {
63 overrides.insert(key, GateRuleOverride::Disabled);
64 }
65 (_, GateTomlValue::Bool(true)) => {} (_, GateTomlValue::String(s)) => {
67 let severity = parse_gate_severity(&s).ok_or_else(|| {
68 D::Error::custom(format!(
69 "invalid gate severity '{s}': expected \"deny\", \"warn\", or \"info\""
70 ))
71 })?;
72 overrides.insert(key, GateRuleOverride::Severity(severity));
73 }
74 }
75 }
76
77 Ok(GateConfig { enabled, overrides })
78 }
79}
80
81fn is_known_gate_rule(rule_name: &str) -> bool {
82 crate::gate::all_gate_rules()
83 .iter()
84 .any(|rule| rule.name == rule_name)
85}
86
87fn parse_gate_severity(s: &str) -> Option<crate::gate::GateSeverity> {
88 use crate::gate::GateSeverity;
89 match s {
90 "deny" => Some(GateSeverity::Deny),
91 "warn" => Some(GateSeverity::Warn),
92 "info" => Some(GateSeverity::Info),
93 _ => None,
94 }
95}