dpp-domain 0.21.0

EU Digital Product Passport domain types, port traits, and per-field disclosure policy
Documentation
//! Toys (EU 2025/2509, DPP mandate 2030).

use serde::{Deserialize, Serialize};

use crate::identifier::ProductIdentifier;

use super::common::SvhcSubstance;

/// Toy product group data for EU Toy Safety Directive and 2025/2509 DPP compliance.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ToyData {
    /// The unique product identifier for the toy model, in whichever EN 18219
    /// clause 5 scheme issued it — a 14-digit GTIN under scheme 1.
    pub product_identifier: ProductIdentifier,
    /// Intended age group, e.g. `"0-3"`, `"3-6"`, `"6-12"`, `"12+"`.
    pub age_group: String,
    /// Primary material, e.g. `"plastic"`, `"wood"`, `"metal"`, `"textile"`, `"mixed"`.
    pub primary_material: String,
    /// Whether the product bears CE marking under the EU Toy Safety Directive.
    pub ce_marking: bool,
    /// ISO 3166-1 alpha-2 country of manufacture.
    pub country_of_origin: String,

    /// SVHC substances present above 0.1% w/w per REACH Article 33.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub svhc_substances: Option<Vec<SvhcSubstance>>,
    /// Whether the toy contains a battery.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub contains_battery: Option<bool>,
    /// Free-text or URL pointing to repairability / spare parts information.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub repairability_info: Option<String>,
}

impl crate::product_group::payload::ProductGroupPayload for ToyData {
    fn product_identifier(&self) -> Option<&crate::identifier::ProductIdentifier> {
        Some(&self.product_identifier)
    }

    /// This act defines no model identifier.
    fn model_identifier(&self) -> Option<&str> {
        None
    }

    /// This group's schema carries a REACH candidate-list declaration.
    fn svhc_substances(&self) -> Option<&[crate::product_group::SvhcSubstance]> {
        self.svhc_substances.as_deref()
    }

    /// This group models no product category, and the catalog declares none.
    /// `age_group` and `primary_material` are properties of a toy, not
    /// partitions of the group — a wooden 3-6 toy is not a category of toy.
    fn product_category(&self) -> Option<&str> {
        None
    }
}