shakrs-json-parser 0.1.0

Parser, validator, scaffolder, and canonical formatter for the shakrs.json workspace config. Zero I/O; no policy-registry knowledge.
Documentation
//! Typed model of a `shakrs.json` document: version, policy enablement, and
//! waivers.

use std::collections::BTreeMap;

use garde::Validate;
use serde::{Deserialize, Serialize};

use crate::types::Waiver;

/// A whole `shakrs.json` document.
#[expect(
    clippy::module_name_repetitions,
    reason = "ShakrsConfig is the canonical document type, named after the shakrs.json file it models, not after the `config` module."
)]
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields)]
pub struct ShakrsConfig {
    /// Schema version. Only `1` is supported.
    #[garde(range(min = 1, max = 1))]
    pub version: u32,
    /// Which registered policies run, and with what parameters.
    #[serde(default)]
    #[garde(dive)]
    pub policies: PoliciesSection,
    /// Per-finding suppressions.
    #[serde(default)]
    #[garde(dive)]
    pub waivers: Vec<Waiver>,
}

/// The `policies` block: a baseline enablement plus per-policy overrides.
#[derive(Debug, Clone, Serialize, Deserialize, Validate)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct PoliciesSection {
    /// Enablement for every registered policy not named in `overrides`.
    /// `true` (default) is opt-out; `false` is opt-in.
    #[serde(default = "crate::runtime::config::default_true")]
    #[garde(skip)]
    pub default_enabled: bool,
    /// Per-policy enablement and parameters, keyed by policy id. Wins over
    /// `default_enabled` for the policies it names.
    #[serde(default)]
    #[garde(skip)]
    pub overrides: BTreeMap<String, PolicyOverride>,
}

/// One entry in `policies.overrides`: either a bare boolean toggle or a
/// detailed object carrying typed parameters.
///
/// `params` stays an opaque `serde_json::Value` here; the owning policy
/// deserializes it into its own input type in the runner, not in this crate.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PolicyOverride {
    /// Shorthand: `true`/`false` toggles the policy with default parameters.
    Enabled(bool),
    /// Full form: explicit enablement plus opaque parameters.
    Detailed {
        /// Whether the policy runs.
        enabled: bool,
        /// Opaque parameters, deserialized by the owning policy later.
        #[serde(default)]
        params: serde_json::Value,
    },
}