Skip to main content

dpp_rules/
lib.rs

1//! `dpp-rules` — pure EU ESPR cross-field regulatory rules.
2//!
3//! Rules are grouped by product group module. Batteries, textiles, and electronics are
4//! the active product groups; all others have placeholder modules and will be populated
5//! in a later phase.
6//!
7//! Inputs are primitive borrowing views so each caller adapts its own
8//! representation — typed structs in core, `serde_json::Value` fields in
9//! plugins — without this crate depending on either. That is why this crate is
10//! kept separate from `dpp-domain`: a regulatory rule has exactly one
11//! implementation, shared by core and the Wasm plugins alike.
12//!
13//! The `bundle` feature (off by default) adds the ruleset-bundle format +
14//! verification seam (the `bundle` module — conditionally compiled, so not
15//! linked here) and pulls in `std` — see that module's docs.
16
17#![cfg_attr(not(feature = "bundle"), no_std)]
18#![forbid(unsafe_code)]
19
20extern crate alloc;
21
22// Only needed when `no_std` is actually active (default build); when the
23// `bundle` feature is on, `no_std` is off and `std` is already available.
24#[cfg(test)]
25extern crate std;
26
27// Shared helpers (cross-product group utilities).
28pub mod common;
29
30// Chemical substance rules — REACH, RoHS, EU 2026/405.
31// SVHC lives here rather than under any single product group because REACH Art. 33
32// applies across textiles, electronics, toys, construction, and more.
33pub mod chemicals;
34
35// Active product groups.
36pub mod batteries;
37pub mod electronics;
38pub mod textiles;
39pub mod unsold_goods;
40
41// Plausibility lints — non-binding findings, never a compliance gate.
42pub mod lint;
43
44// Placeholder product groups — rules to be implemented in a later phase.
45pub mod construction;
46pub mod metals;
47pub mod toys;
48
49// Canonical JCS content hashing — the one hasher shared by the bundle
50// verifier and by downstream evidence/dossier consumers, so an integrity
51// hash cannot drift between the code that writes it and the code that checks it.
52#[cfg(feature = "bundle")]
53pub mod canonical;
54
55// Ruleset-bundle format + verification seam (signed, versioned Compliance
56// Current bundles). Optional: signing and hot-swap runtime state stay
57// engine-side; this crate only carries the open format + fail-closed verify.
58#[cfg(feature = "bundle")]
59pub mod bundle;
60
61// ── Crate-root re-exports ────────────────────────────────────────────────────
62// Preserved for backward compatibility with existing callers
63// (dpp-domain adapters, dpp-plugin-sdk::rules).
64
65pub use chemicals::cas::validate_cas_format;
66pub use chemicals::surfactants::{
67    SURFACTANT_BANDS, SurfactantInput, surfactant_band_valid, validate_surfactants,
68};
69pub use chemicals::svhc::{
70    CandidateListProvenance, ECHA_CANDIDATE_LIST, ECHA_CANDIDATE_LIST_AS_OF,
71    ECHA_CANDIDATE_LIST_OFFICIAL_COUNT, SVHC_THRESHOLD_PCT, SvhcFinding, SvhcFindingKind,
72    SvhcInput, candidate_list_provenance, check_svhc_declarations, validate_svhc_substances,
73};
74pub use common::country::country_code_valid;
75pub use textiles::fibre::{
76    FIBRE_SUM_TOLERANCE, FibreInput, fibre_sum_ok, validate_fibre_composition,
77};
78
79/// Compile-checks this crate's README examples.
80///
81/// A README example is a public claim about the API, and nothing else in the
82/// build compiles one. Without this, a README can advertise a function that
83/// does not exist — which is exactly what happened before this harness landed.
84#[cfg(doctest)]
85#[doc = include_str!("../README.md")]
86struct ReadmeDoctests;