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}