Skip to main content

dpp_domain/validation/
mod.rs

1//! JSON Schema + cross-field validation for product group-specific DPP data.
2//!
3//! The schema step resolves against the crate's **embedded**
4//! [`VersionedSchemaRegistry`](crate::schemas::VersionedSchemaRegistry) — built
5//! once from the compile-time schemas — at the version the
6//! [`ProductGroupCatalog`](crate::ProductGroupCatalog) marks current for the product group; there
7//! are no per-product group validators and no hardcoded versions here. Schemas
8//! registered at runtime into a separate registry instance are **not** seen by
9//! these free functions (nor by `Passport::validate`); validate against those
10//! through that registry directly (its fail-closed `validate_strict`).
11//! Cross-field regulatory rules (which JSON Schema cannot express, e.g. "fibre
12//! percentages sum to ~100%") come from `dpp-rules` via the `dpp-domain` adapters.
13//!
14//! **Note**: excluded from wasm32 builds since jsonschema depends on reqwest's
15//! blocking API.
16//!
17//! ## Module layout
18//!
19//! - [`validator`] — the [`ProductGroupValidator`] trait + [`ProductGroupValidatorRegistry`]
20//!   extensibility seam (a port-like abstraction, different change-cadence).
21//! - [`functions`] — the `validate_*` free functions (schema + cross-field).
22//! - [`batch`] — batch validation over multiple product group-data items.
23//! - [`personal_data`] — the write-time check that a field able to hold personal
24//!   data carries the operator's statement about it.
25
26// Only the schema pass needs gating. `rules` is a thin adapter onto `dpp-rules`
27// and is pure, so it stays available on every target — the module-level gate
28// that used to sit here withheld it from wasm32 for no reason of its own.
29#[cfg(not(target_arch = "wasm32"))]
30pub mod batch;
31#[cfg(not(target_arch = "wasm32"))]
32pub mod functions;
33#[cfg(not(target_arch = "wasm32"))]
34pub mod personal_data;
35pub mod rules;
36#[cfg(not(target_arch = "wasm32"))]
37pub mod validator;
38
39#[cfg(all(test, not(target_arch = "wasm32")))]
40mod personal_data_tests;
41#[cfg(all(test, not(target_arch = "wasm32")))]
42mod tests;
43
44#[cfg(not(target_arch = "wasm32"))]
45pub use batch::{BatchValidationItem, batch_errors, validate_product_group_data_batch};
46#[cfg(not(target_arch = "wasm32"))]
47pub use functions::{
48    validate_passport, validate_product_group_data, validate_product_group_data_with_registry,
49    validate_raw_product_group_data,
50};
51#[cfg(not(target_arch = "wasm32"))]
52pub use personal_data::{PERSONAL_DATA_MARK, check_personal_data, personal_data_marks};
53pub use rules::{
54    battery_recycled_chemistry_conflicts, unsold_goods_annex_vii_heading,
55    unsold_goods_cn_depth_is_correct, validate_battery_operating_temp, validate_fibre_composition,
56    validate_surfactants, validate_svhc_substances,
57};
58#[cfg(not(target_arch = "wasm32"))]
59pub use validator::{ProductGroupValidator, ProductGroupValidatorRegistry};
60
61// `FieldError` and `ValidationErrors` live in `crate::error::field`
62// (wasm-safe) so `DppError` can carry structured validation detail.