1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! Furniture (EU ESPR Working Plan 2025-2030, mandate ~2028-2031).
use serde::{Deserialize, Serialize};
use crate::identifier::ProductIdentifier;
use super::common::SvhcSubstance;
/// Furniture product group data for EU ESPR DPP compliance.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct FurnitureData {
/// The unique product identifier for the furniture product, in whichever EN 18219
/// clause 5 scheme issued it — a 14-digit GTIN under scheme 1.
pub product_identifier: ProductIdentifier,
/// Product type, e.g. `"chair"`, `"table"`, `"sofa"`, `"mattress"`, `"shelf"`, `"other"`.
pub product_type: String,
/// Primary material, e.g. `"solid-wood"`, `"engineered-wood"`, `"metal"`, `"upholstered"`, `"mixed"`.
pub primary_material: String,
/// ISO 3166-1 alpha-2 country of manufacture.
pub country_of_origin: String,
/// Carbon footprint in kg CO₂e per unit.
#[serde(skip_serializing_if = "Option::is_none")]
pub co2e_per_unit_kg: Option<f64>,
/// Recycled content as a percentage of total weight (0.0–100.0).
#[serde(skip_serializing_if = "Option::is_none")]
pub recycled_content_pct: Option<f64>,
/// Repairability score (0.0–10.0, non-regulatory heuristic — not EN 45554 / EU 2023/1669).
#[serde(skip_serializing_if = "Option::is_none")]
pub repairability_score: Option<f64>,
/// 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>>,
/// URL to disassembly / deconstruction instructions.
#[serde(skip_serializing_if = "Option::is_none")]
pub disassembly_instructions_url: Option<String>,
/// End-of-life disposal or recycling instructions.
#[serde(skip_serializing_if = "Option::is_none")]
pub end_of_life_instructions: Option<String>,
}
impl crate::product_group::payload::ProductGroupPayload for FurnitureData {
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()
}
/// The furniture type. Constrained by the `productType` enum in this
/// group's schema — which no longer offers `mattress`, since a mattress is
/// its own product group rather than a value here.
fn product_category(&self) -> Option<&str> {
Some(&self.product_type)
}
}