pub struct AssessmentClock {
pub law_in_force_on: NaiveDate,
pub computed_at: DateTime<Utc>,
}Expand description
The two dates a compliance computation needs. They are never the same field.
EU staged obligations attach at a regulated triggering event — for Regulation (EU) 2023/1542 Articles 7, 8 and 10 that is placing on the market or putting into service. Which law governs a given product is therefore fixed at that moment, and does not change when the product is reassessed years later. A battery lawfully placed on the market in 2030 does not acquire the 18 August 2031 minimums by being audited in 2033.
There is deliberately no AssessmentClock::now(). A wall-clock
constructor is precisely the mistake this type exists to prevent: it would
let every determination silently re-derive the governing law from whichever
day the calculation happened to run.
Fields§
§law_in_force_on: NaiveDateWhich law applies. Derived from the regulated triggering event — never from today’s date.
computed_at: DateTime<Utc>When this computation ran. Receipt provenance only; this never selects a ruleset.
Implementations§
Source§impl AssessmentClock
impl AssessmentClock
Sourcepub fn placed_on(law_in_force_on: NaiveDate) -> Self
pub fn placed_on(law_in_force_on: NaiveDate) -> Self
Build a clock for a product whose governing law was fixed on
law_in_force_on, computed now.
The wall clock supplies computed_at and nothing else.
law_in_force_on must come from the product’s own record — the
passport’s placing-on-market date — and never from Utc::now().
Examples found in repository?
12fn main() {
13 // The date the governing law attached to this product. In a real caller this
14 // comes from the passport's placing-on-market date, never from the clock.
15 let clock = AssessmentClock::placed_on(NaiveDate::from_ymd_opt(2026, 1, 1).unwrap());
16
17 // Cradle-to-gate CO₂e for a small battery (materials + manufacturing energy).
18 let footprint = co2e::calculate(
19 &Co2eInputs {
20 materials: vec![
21 MaterialFootprint {
22 mass_kg: 0.5,
23 emission_factor_kg_co2e_per_kg: 8.0, // e.g. recycled aluminium
24 },
25 MaterialFootprint {
26 mass_kg: 0.2,
27 emission_factor_kg_co2e_per_kg: 3.0,
28 },
29 ],
30 energy_kwh: 1.5,
31 grid_factor_kg_co2e_per_kwh: 0.4,
32 },
33 &CradleToGateRuleset,
34 clock,
35 )
36 .expect("valid inputs");
37
38 println!(
39 "CO₂e: {:.2} kg (materials {:.2} + energy {:.2}) stages={:?} receipt={}",
40 footprint.total_co2e_kg,
41 footprint.material_co2e_kg,
42 footprint.energy_co2e_kg,
43 footprint.declared_stages,
44 footprint.receipt.receipt_id,
45 );
46 for (i, line) in footprint.material_breakdown.iter().enumerate() {
47 println!(
48 " material[{i}]: {:.3} kg × {:.3} kg CO₂e/kg = {:.3} kg CO₂e",
49 line.mass_kg, line.emission_factor_kg_co2e_per_kg, line.co2e_kg
50 );
51 }
52
53 // Simplified repairability heuristic band (A–E) for a smartphone — not the
54 // EU 2023/1669 regulatory class.
55 let rep = repairability::calculate(
56 &RepairabilityInputs {
57 disassembly: 2,
58 spare_parts: 2,
59 repair_info: 1,
60 diagnostic_tools: 1,
61 software_updatability: 2,
62 customer_support: 1,
63 },
64 &SimplifiedRepairabilityHeuristic,
65 clock,
66 )
67 .expect("valid inputs");
68
69 println!(
70 "Repairability: {} ({:.2}/10) ruleset={}@{}",
71 rep.class, rep.numeric_score, rep.receipt.ruleset_id, rep.receipt.ruleset_version,
72 );
73 let c = &rep.contributions;
74 println!(
75 " disassembly={:.2} spare_parts={:.2} repair_info={:.2} \
76 diagnostic={:.2} software={:.2} support={:.2}",
77 c.disassembly,
78 c.spare_parts,
79 c.repair_info,
80 c.diagnostic_tools,
81 c.software_updatability,
82 c.customer_support,
83 );
84}Trait Implementations§
Source§impl Clone for AssessmentClock
impl Clone for AssessmentClock
Source§fn clone(&self) -> AssessmentClock
fn clone(&self) -> AssessmentClock
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more