Skip to main content

dpp_domain/schemas/
mod.rs

1//! Versioned schema registry for EU ESPR sector schemas.
2//!
3//! The registry ships with compile-time embedded schemas and supports runtime
4//! registration of new versions ("hot-reload"). This lets a running platform
5//! absorb delegated-act schema changes without recompilation.
6//!
7//! Embedded schemas come from `dpp-core/schemas/{sector}/v{version}.json`.
8//! Runtime schemas are registered via [`VersionedSchemaRegistry::register`].
9
10use semver::Version;
11
12mod embedded;
13mod registry;
14#[cfg(test)]
15mod tests;
16
17pub use registry::VersionedSchemaRegistry;
18
19// ─── Schema origin ──────────────────────────────────────────────────────────
20
21/// Tracks whether a schema was baked in at compile time or loaded at runtime.
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23#[non_exhaustive]
24pub enum SchemaOrigin {
25    /// Compiled into the binary via `include_str!()`.
26    Embedded,
27    /// Loaded at runtime via [`VersionedSchemaRegistry::register`].
28    Runtime,
29}
30
31// ─── Schema entry ───────────────────────────────────────────────────────────
32
33/// A single (sector, version) → JSON schema mapping.
34#[derive(Debug, Clone)]
35pub struct SchemaEntry {
36    pub sector: String,
37    pub version: Version,
38    pub json: String,
39    pub origin: SchemaOrigin,
40}
41
42// ─── Registration error ─────────────────────────────────────────────────────
43
44/// Errors returned by [`VersionedSchemaRegistry::register`].
45#[derive(Debug, Clone, PartialEq, Eq)]
46#[non_exhaustive]
47pub enum SchemaRegistrationError {
48    /// The provided JSON string is not valid JSON.
49    InvalidJson(String),
50    /// A schema for this (sector, version) already exists.
51    /// Use `register_or_replace` to overwrite.
52    AlreadyExists { sector: String, version: Version },
53    /// The version string is not valid semver.
54    InvalidVersion(String),
55}
56
57impl std::fmt::Display for SchemaRegistrationError {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        match self {
60            Self::InvalidJson(msg) => write!(f, "invalid JSON schema: {msg}"),
61            Self::AlreadyExists { sector, version } => {
62                write!(f, "schema already exists for {sector} v{version}")
63            }
64            Self::InvalidVersion(v) => write!(f, "invalid semver version: {v}"),
65        }
66    }
67}
68
69impl std::error::Error for SchemaRegistrationError {}