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
37const SIMILAR_CODE_SNAPSHOT_SCHEMA_JSON: &str =
42 include_str!("../similar-code-snapshot-schema.json");
43
44static SIMILAR_CODE_SNAPSHOT_SCHEMA: LazyLock<serde_json::Value> = LazyLock::new(|| {
45 serde_json::from_str(SIMILAR_CODE_SNAPSHOT_SCHEMA_JSON)
46 .unwrap_or_else(|_| serde_json::Value::Object(serde_json::Map::new()))
47});
48
49#[must_use]
52pub fn similar_code_snapshot_schema() -> serde_json::Value {
53 SIMILAR_CODE_SNAPSHOT_SCHEMA.clone()
54}
55
56#[must_use]
64pub fn default_rule_severities() -> serde_json::Value {
65 DEFAULT_RULE_SEVERITIES.clone()
66}
67
68#[must_use]
71pub fn is_rule_severity_key(key: &str) -> bool {
72 DEFAULT_RULE_SEVERITIES
73 .get(key)
74 .is_some_and(serde_json::Value::is_string)
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn schemas_are_json_objects_with_properties() {
83 for (label, schema) in [
84 ("config", config_schema()),
85 ("plugin", plugin_schema()),
86 ("rule-pack", rule_pack_schema()),
87 ] {
88 assert!(
89 schema
90 .get("properties")
91 .is_some_and(serde_json::Value::is_object),
92 "{label} schema must be an object schema with properties"
93 );
94 }
95 }
96
97 #[test]
98 fn default_severities_are_keyed_by_config_key() {
99 let defaults = default_rule_severities();
100 assert_eq!(defaults["unused-exports"], "error");
101 assert_eq!(defaults["security-sink"], "off");
102 assert!(
103 defaults.get("unused_exports").is_none(),
104 "keys are kebab-case"
105 );
106 assert!(is_rule_severity_key("coverage-gaps"));
107 assert!(!is_rule_severity_key("code-duplication"));
108 }
109}