1use std::sync::LazyLock;
9
10use fallow_config::{ExternalPluginDef, FallowConfig, RulePackDef, RulesConfig};
11
12static DEFAULT_RULE_SEVERITIES: LazyLock<serde_json::Value> = LazyLock::new(|| {
15 serde_json::to_value(RulesConfig::default())
16 .unwrap_or_else(|_| serde_json::Value::Object(serde_json::Map::new()))
17});
18
19#[must_use]
21pub fn config_schema() -> serde_json::Value {
22 FallowConfig::json_schema()
23}
24
25#[must_use]
27pub fn plugin_schema() -> serde_json::Value {
28 ExternalPluginDef::json_schema()
29}
30
31#[must_use]
33pub fn rule_pack_schema() -> serde_json::Value {
34 RulePackDef::json_schema()
35}
36
37#[must_use]
45pub fn default_rule_severities() -> serde_json::Value {
46 DEFAULT_RULE_SEVERITIES.clone()
47}
48
49#[must_use]
52pub fn is_rule_severity_key(key: &str) -> bool {
53 DEFAULT_RULE_SEVERITIES
54 .get(key)
55 .is_some_and(serde_json::Value::is_string)
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn schemas_are_json_objects_with_properties() {
64 for (label, schema) in [
65 ("config", config_schema()),
66 ("plugin", plugin_schema()),
67 ("rule-pack", rule_pack_schema()),
68 ] {
69 assert!(
70 schema
71 .get("properties")
72 .is_some_and(serde_json::Value::is_object),
73 "{label} schema must be an object schema with properties"
74 );
75 }
76 }
77
78 #[test]
79 fn default_severities_are_keyed_by_config_key() {
80 let defaults = default_rule_severities();
81 assert_eq!(defaults["unused-exports"], "error");
82 assert_eq!(defaults["security-sink"], "off");
83 assert!(
84 defaults.get("unused_exports").is_none(),
85 "keys are kebab-case"
86 );
87 assert!(is_rule_severity_key("coverage-gaps"));
88 assert!(!is_rule_severity_key("code-duplication"));
89 }
90}