Skip to main content

dpp_calc/kernel/
ruleset.rs

1//! Ruleset identity and validity period types used across all `dpp-calc` calculators.
2
3use chrono::NaiveDate;
4use serde::{Deserialize, Serialize};
5
6/// Opaque machine-readable identifier for a regulatory ruleset.
7///
8/// Examples: `"repairability-heuristic-v1"`, `"battery-cfb"`.
9#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub struct RulesetId(pub String);
11
12/// Semver-shaped version for a ruleset, tracking parameter changes across
13/// delegated-act amendments.
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub struct RulesetVersion(pub String);
16
17/// The calendar range within which a ruleset version is legally valid.
18#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
19pub struct EffectiveDateBound {
20    /// First day this ruleset version applies (inclusive).
21    pub from: NaiveDate,
22    /// Last day this ruleset version applies (inclusive), or `None` if open-ended.
23    pub until: Option<NaiveDate>,
24}
25
26impl EffectiveDateBound {
27    pub fn open(from: NaiveDate) -> Self {
28        Self { from, until: None }
29    }
30
31    pub fn is_active_on(&self, date: NaiveDate) -> bool {
32        date >= self.from && self.until.is_none_or(|u| date <= u)
33    }
34}
35
36/// Structured legal citation for a regulatory ruleset.
37///
38/// Embedded in every [`Ruleset`] implementation so the authoritative source can
39/// be located programmatically — without reading source comments or external docs.
40/// This is the primary audit anchor for notified bodies.
41#[derive(Debug, Clone, Serialize)]
42pub struct RegulatoryBasis {
43    /// EU regulation or directive number (e.g. `"EU 2023/1669"`).
44    pub regulation: &'static str,
45    /// Relevant article and/or annex (e.g. `"Annex II, Annex III"`).
46    pub article: &'static str,
47    /// Harmonised standard used for the methodology (e.g. `"EN 45554:2021"`).
48    pub standard: Option<&'static str>,
49    /// JRC or other technical study underpinning the parameters (e.g. `"JRC128649"`).
50    pub technical_study: Option<&'static str>,
51    /// EUR-Lex or Official Journal URL for the authoritative source text.
52    pub source_url: Option<&'static str>,
53    /// Base ID of the successor ruleset version, if this one has been superseded.
54    /// Set when `effective_dates.until` is populated.
55    pub superseded_by: Option<&'static str>,
56}
57
58/// Common interface for all regulatory rulesets embedded in this crate.
59pub trait Ruleset {
60    fn id(&self) -> &RulesetId;
61    fn version(&self) -> &RulesetVersion;
62    fn effective_dates(&self) -> &EffectiveDateBound;
63    /// Structured citation for the EU regulation that mandates this calculation.
64    fn regulatory_basis(&self) -> &RegulatoryBasis;
65}