Skip to main content

matter_clusters/
lib.rs

1//! Typed Matter cluster definitions — generated from the Matter spec.
2//!
3//! Per-cluster attribute / command / struct **codecs** (encode/decode to Matter
4//! TLV), feature bitflags, enums (with an `Unknown(n)` variant for
5//! forward-compatibility), and bitmaps. The cluster modules live under
6//! [`gen`]; the hand-written foundation is [`Nullable<T>`](types::Nullable)
7//! (distinct from `Option`), [`ClusterError`](error::ClusterError), and
8//! [`datatypes::SemanticTagStruct`].
9//!
10//! # Pipeline
11//!
12//! The `gen/` modules are generated, not hand-written: a pinned `@matter/model`
13//! dump becomes the committed `xtask/model/clusters.json`, which
14//! `cargo xtask codegen` turns into the committed `src/gen/*.rs`. CI gates drift
15//! with `cargo xtask codegen --check`. **Do not edit `src/gen/` by hand** —
16//! change the emitter in `xtask/src/codegen/` and regenerate.
17//!
18//! Correctness: the generated codecs are **byte-parity tested against matter.js
19//! 0.16.11** (`test-vectors/clusters/`), with `proptest` roundtrips and a
20//! `cargo-fuzz` target.
21//!
22//! # Clusters
23//!
24//! M7 (byte-parity tested): `BasicInformation`, `Descriptor`, `Identify`,
25//! `OnOff`, `LevelControl`, `ColorControl`, `OccupancySensing`,
26//! `TemperatureMeasurement`, `RelativeHumidityMeasurement`, and `DoorLock`
27//! (Aliro features excluded). M9-A2.1 pilot (decode-smoke tested):
28//! `IlluminanceMeasurement`, `PressureMeasurement`, `FlowMeasurement`,
29//! `BooleanState`, and `Switch`. M9-A2.2 energy (decode-smoke + one nested
30//! byte-parity vector): `PowerSource`, `ElectricalPowerMeasurement`,
31//! `ElectricalEnergyMeasurement`, and `AirQuality`. M9-A2.3 actuators
32//! (roundtrip + decode-smoke, with a byte-parity vector for the list-typed
33//! `AtomicRequest` command): `Thermostat`, `FanControl`,
34//! `ThermostatUserInterfaceConfiguration`, `PumpConfigurationAndControl`, and
35//! `WindowCovering`. M9-A2.4 utility (decode-smoke + one struct-with-byte-fields
36//! byte-parity vector for `GeneralDiagnostics` `NetworkInterface`): `Groups`,
37//! `Binding`, `GeneralDiagnostics`, `FixedLabel`, and `UserLabel`. M9-A2.5
38//! management (codecs only — protocol logic deferred to later milestones;
39//! decode-smoke + a byte-parity vector for the recursive list-of-struct command
40//! encode `AccessControl::ReviewFabricRestrictions`): `AccessControl`,
41//! `GroupKeyManagement`, `AdministratorCommissioning`, and
42//! `OtaSoftwareUpdateRequestor`.
43//!
44//! For any attribute not covered by these typed codecs — optional,
45//! manufacturer-specific, or a cluster not in this list — the generic `Value`
46//! path in `matter-controller` remains the universal answer.
47//!
48//! # Usage
49//!
50//! Codecs are free functions per attribute/command. Encoders return a standalone
51//! anonymous-tagged TLV element (ready to embed in an Interaction Model
52//! request); decoders take the attribute value bytes from a report.
53//!
54//! ```
55//! use matter_clusters::gen::{basic_information, on_off};
56//!
57//! // Command payload — embed in an InvokeRequest (see the `control_onoff` example).
58//! let _toggle = on_off::encode_toggle();
59//!
60//! // Attribute roundtrips: encode a value, decode it back.
61//! let tlv = on_off::encode_on_time(30);
62//! assert_eq!(on_off::decode_on_time(&tlv)?, 30);
63//!
64//! let tlv = basic_information::encode_node_label(&"living room".to_string());
65//! assert_eq!(basic_information::decode_node_label(&tlv)?, "living room");
66//! # Ok::<(), matter_clusters::error::ClusterError>(())
67//! ```
68//!
69//! See `crates/matter-commissioning/examples/control_onoff.rs` for an
70//! end-to-end read / toggle / write against a real device.
71//!
72//! # Scope — reading attributes beyond these clusters
73//!
74//! Typed codecs exist for these clusters' **mandatory and optional** attributes
75//! (a device may not implement a given optional attribute — it then returns
76//! `UNSUPPORTED_ATTRIBUTE`). To read attributes of clusters NOT in this set, or
77//! manufacturer-specific attributes, use the generic Interaction Model path:
78//! `matter_interaction::parse_report_data` decodes any attribute to a
79//! `(AttributePath, matter_codec::Value)` pair without a typed codec. A
80//! high-level generic + wildcard read API, and more typed clusters, arrive in
81//! later milestones.
82
83#![forbid(unsafe_code)]
84
85pub mod datatypes;
86pub mod error;
87pub mod types;
88
89pub use datatypes::SemanticTagStruct;
90
91pub mod gen;
92
93#[cfg(test)]
94mod golden;