dpp-rules 0.21.0

Pure EU ESPR cross-field regulatory rules, shared by dpp-domain and the Wasm product group plugins
Documentation
//! `dpp-rules` — pure EU ESPR cross-field regulatory rules.
//!
//! Rules are grouped by product group module. Batteries, textiles, and electronics are
//! the active product groups; all others have placeholder modules and will be populated
//! in a later phase.
//!
//! Inputs are primitive borrowing views so each caller adapts its own
//! representation — typed structs in core, `serde_json::Value` fields in
//! plugins — without this crate depending on either. That is why this crate is
//! kept separate from `dpp-domain`: a regulatory rule has exactly one
//! implementation, shared by core and the Wasm plugins alike.
//!
//! The `bundle` feature (off by default) adds the ruleset-bundle format +
//! verification seam (the `bundle` module — conditionally compiled, so not
//! linked here) and pulls in `std` — see that module's docs.

#![cfg_attr(not(feature = "bundle"), no_std)]
#![forbid(unsafe_code)]

extern crate alloc;

// Only needed when `no_std` is actually active (default build); when the
// `bundle` feature is on, `no_std` is off and `std` is already available.
#[cfg(test)]
extern crate std;

// Shared helpers (cross-product group utilities).
pub mod common;

// Chemical substance rules — REACH, RoHS, EU 2026/405.
// SVHC lives here rather than under any single product group because REACH Art. 33
// applies across textiles, electronics, toys, construction, and more.
pub mod chemicals;

// Active product groups.
pub mod batteries;
pub mod electronics;
pub mod textiles;
pub mod unsold_goods;

// Lineage rules — how one passport may claim to derive from another. Top-level
// rather than per product group because the edges are envelope fields every
// product group carries, and ESPR Art. 11(d) makes the linkage obligation
// framework-level.
pub mod lineage;

// Plausibility lints — non-binding findings, never a compliance gate.
pub mod lint;

// Placeholder product groups — rules to be implemented in a later phase.
pub mod construction;
pub mod metals;
pub mod toys;

// Canonical JCS content hashing — the one hasher shared by the bundle
// verifier and by downstream evidence/dossier consumers, so an integrity
// hash cannot drift between the code that writes it and the code that checks it.
#[cfg(feature = "bundle")]
pub mod canonical;

// Ruleset-bundle format + verification seam (signed, versioned Compliance
// Current bundles). Optional: signing and hot-swap runtime state stay
// host-side; this crate only carries the open format + fail-closed verify.
#[cfg(feature = "bundle")]
pub mod bundle;

// ── Crate-root re-exports ────────────────────────────────────────────────────
// Preserved for backward compatibility with existing callers
// (dpp-domain adapters, dpp-plugin-sdk::rules).

pub use chemicals::cas::validate_cas_format;
pub use chemicals::surfactants::{
    SURFACTANT_BANDS, SurfactantInput, surfactant_band_valid, validate_surfactants,
};
pub use chemicals::svhc::{
    CandidateList, ECHA_CANDIDATE_LIST, ECHA_CANDIDATE_LIST_AS_OF,
    ECHA_CANDIDATE_LIST_OFFICIAL_COUNT, SVHC_THRESHOLD_PCT, SvhcFinding, SvhcFindingKind,
    SvhcInput, check_svhc_declarations, check_svhc_declarations_embedded, validate_svhc_substances,
};
pub use common::country::country_code_valid;
pub use textiles::fibre::{
    FIBRE_SUM_TOLERANCE, FibreInput, fibre_sum_ok, validate_fibre_composition,
};

/// Compile-checks this crate's README examples.
///
/// A README example is a public claim about the API, and nothing else in the
/// build compiles one. Without this, a README can advertise a function that
/// does not exist — which is exactly what happened before this harness landed.
#[cfg(doctest)]
#[doc = include_str!("../README.md")]
struct ReadmeDoctests;