Skip to main content

matter_clusters/gen/
descriptor.rs

1//! Descriptor cluster (0x001D).
2//! @generated by `cargo xtask codegen` — do not edit.
3
4#![allow(
5    clippy::all,
6    clippy::pedantic,
7    dead_code,
8    unreachable_pub,
9    unused_imports
10)]
11
12use crate::datatypes::SemanticTagStruct;
13use crate::error::ClusterError;
14use crate::types::Nullable;
15use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter, Value};
16
17/// Cluster ID.
18pub const CLUSTER_ID: u32 = 0x001D;
19/// Cluster revision.
20pub const CLUSTER_REVISION: u16 = 3;
21
22/// Command IDs (requests and responses).
23pub mod command_id {}
24
25/// Attribute IDs (cluster-specific).
26pub mod attribute_id {
27    /// `DeviceTypeList`.
28    pub const DEVICE_TYPE_LIST: u32 = 0x0000;
29    /// `ServerList`.
30    pub const SERVER_LIST: u32 = 0x0001;
31    /// `ClientList`.
32    pub const CLIENT_LIST: u32 = 0x0002;
33    /// `PartsList`.
34    pub const PARTS_LIST: u32 = 0x0003;
35    /// `TagList`.
36    pub const TAG_LIST: u32 = 0x0004;
37    /// `EndpointUniqueId`.
38    pub const ENDPOINT_UNIQUE_ID: u32 = 0x0005;
39}
40
41bitflags::bitflags! {
42    /// `Descriptor` feature bits (FeatureMap).
43    #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
44    pub struct Feature: u32 {
45        /// TagList (TAGLIST).
46        const TAGLIST = 1 << 0;
47    }
48}
49
50/// `DeviceTypeStruct` struct.
51#[derive(Clone, Debug, PartialEq)]
52#[non_exhaustive]
53pub struct DeviceTypeStruct {
54    /// Field DeviceType (tag 0).
55    pub device_type: u32,
56    /// Field Revision (tag 1).
57    pub revision: u16,
58}
59
60impl DeviceTypeStruct {
61    /// Decode the fields of an already-opened anonymous structure
62    /// (reader positioned after the struct start; consumes to its end).
63    ///
64    /// # Errors
65    /// Returns [`ClusterError`] on a malformed structure or missing required field.
66    pub fn decode_from(r: &mut TlvReader<'_>) -> Result<Self, ClusterError> {
67        let mut f_device_type: Option<u32> = None;
68        let mut f_revision: Option<u16> = None;
69        loop {
70            match r.next()? {
71                Some(Element::ContainerEnd) => break,
72                Some(Element::Scalar {
73                    tag: Tag::Context(0),
74                    value: Value::Uint(v),
75                }) => {
76                    f_device_type = Some(
77                        u32::try_from(v).map_err(|_| ClusterError::InvalidLength("DeviceType"))?,
78                    )
79                }
80                Some(Element::Scalar {
81                    tag: Tag::Context(1),
82                    value: Value::Uint(v),
83                }) => {
84                    f_revision = Some(
85                        u16::try_from(v).map_err(|_| ClusterError::InvalidLength("Revision"))?,
86                    )
87                }
88                None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
89                Some(Element::ContainerStart { .. }) => r.skip_container()?,
90                Some(_) => {} // unknown/future scalar — skip
91            }
92        }
93        Ok(Self {
94            device_type: f_device_type.ok_or(ClusterError::MissingField("DeviceType"))?,
95            revision: f_revision.ok_or(ClusterError::MissingField("Revision"))?,
96        })
97    }
98    /// Decode from a standalone anonymous TLV structure.
99    ///
100    /// # Errors
101    /// Returns [`ClusterError`] if the bytes are not an anonymous structure or a field is malformed.
102    pub fn decode(tlv: &[u8]) -> Result<Self, ClusterError> {
103        let mut r = TlvReader::new(tlv);
104        match r.next()? {
105            Some(Element::ContainerStart {
106                kind: ContainerKind::Structure,
107                ..
108            }) => {}
109            _ => {
110                return Err(ClusterError::UnexpectedType {
111                    context: "DeviceTypeStruct",
112                })
113            }
114        }
115        Self::decode_from(&mut r)
116    }
117    /// Write this struct's fields into an already-open container.
118    #[allow(clippy::expect_used)] // Vec-backed TlvWriter is infallible.
119    pub fn write_fields(&self, w: &mut TlvWriter<'_>) {
120        w.put_uint(Tag::Context(0), u64::from(self.device_type))
121            .expect("infallible: vec writer");
122        w.put_uint(Tag::Context(1), u64::from(self.revision))
123            .expect("infallible: vec writer");
124    }
125    /// Encode as a standalone anonymous TLV structure.
126    #[must_use]
127    #[allow(clippy::expect_used)] // Vec-backed TlvWriter is infallible.
128    pub fn encode(&self) -> Vec<u8> {
129        let mut buf = Vec::new();
130        let mut w = TlvWriter::new(&mut buf);
131        w.start_structure(Tag::Anonymous)
132            .expect("infallible: vec writer");
133        self.write_fields(&mut w);
134        w.end_container().expect("infallible: vec writer");
135        buf
136    }
137}
138
139/// Decode the `DeviceTypeList` attribute value.
140///
141/// # Errors
142/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
143pub fn decode_device_type_list(tlv: &[u8]) -> Result<Vec<DeviceTypeStruct>, ClusterError> {
144    let mut r = TlvReader::new(tlv);
145    match r.next()? {
146        Some(Element::ContainerStart {
147            kind: ContainerKind::Array,
148            ..
149        }) => {}
150        _ => {
151            return Err(ClusterError::UnexpectedType {
152                context: "DeviceTypeList",
153            })
154        }
155    }
156    let r = &mut r;
157    let mut out = Vec::new();
158    loop {
159        match r.next()? {
160            Some(Element::ContainerEnd) => break,
161            Some(Element::ContainerStart {
162                kind: ContainerKind::Structure,
163                ..
164            }) => {
165                out.push(DeviceTypeStruct::decode_from(r)?);
166            }
167            None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
168            Some(Element::ContainerStart { .. }) => r.skip_container()?,
169            Some(_) => {} // skip unknown scalar
170        }
171    }
172    Ok(out)
173}
174
175/// Decode the `ServerList` attribute value.
176///
177/// # Errors
178/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
179pub fn decode_server_list(tlv: &[u8]) -> Result<Vec<u32>, ClusterError> {
180    let mut r = TlvReader::new(tlv);
181    match r.next()? {
182        Some(Element::ContainerStart {
183            kind: ContainerKind::Array,
184            ..
185        }) => {}
186        _ => {
187            return Err(ClusterError::UnexpectedType {
188                context: "ServerList",
189            })
190        }
191    }
192    let r = &mut r;
193    let mut out = Vec::new();
194    loop {
195        match r.next()? {
196            Some(Element::ContainerEnd) => break,
197            Some(Element::Scalar {
198                value: Value::Uint(v),
199                ..
200            }) => {
201                out.push(u32::try_from(v).map_err(|_| ClusterError::InvalidLength("ServerList"))?)
202            }
203            None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
204            Some(Element::ContainerStart { .. }) => r.skip_container()?,
205            Some(_) => {} // skip unknown scalar
206        }
207    }
208    Ok(out)
209}
210
211/// Decode the `ClientList` attribute value.
212///
213/// # Errors
214/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
215pub fn decode_client_list(tlv: &[u8]) -> Result<Vec<u32>, ClusterError> {
216    let mut r = TlvReader::new(tlv);
217    match r.next()? {
218        Some(Element::ContainerStart {
219            kind: ContainerKind::Array,
220            ..
221        }) => {}
222        _ => {
223            return Err(ClusterError::UnexpectedType {
224                context: "ClientList",
225            })
226        }
227    }
228    let r = &mut r;
229    let mut out = Vec::new();
230    loop {
231        match r.next()? {
232            Some(Element::ContainerEnd) => break,
233            Some(Element::Scalar {
234                value: Value::Uint(v),
235                ..
236            }) => {
237                out.push(u32::try_from(v).map_err(|_| ClusterError::InvalidLength("ClientList"))?)
238            }
239            None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
240            Some(Element::ContainerStart { .. }) => r.skip_container()?,
241            Some(_) => {} // skip unknown scalar
242        }
243    }
244    Ok(out)
245}
246
247/// Decode the `PartsList` attribute value.
248///
249/// # Errors
250/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
251pub fn decode_parts_list(tlv: &[u8]) -> Result<Vec<u16>, ClusterError> {
252    let mut r = TlvReader::new(tlv);
253    match r.next()? {
254        Some(Element::ContainerStart {
255            kind: ContainerKind::Array,
256            ..
257        }) => {}
258        _ => {
259            return Err(ClusterError::UnexpectedType {
260                context: "PartsList",
261            })
262        }
263    }
264    let r = &mut r;
265    let mut out = Vec::new();
266    loop {
267        match r.next()? {
268            Some(Element::ContainerEnd) => break,
269            Some(Element::Scalar {
270                value: Value::Uint(v),
271                ..
272            }) => out.push(u16::try_from(v).map_err(|_| ClusterError::InvalidLength("PartsList"))?),
273            None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
274            Some(Element::ContainerStart { .. }) => r.skip_container()?,
275            Some(_) => {} // skip unknown scalar
276        }
277    }
278    Ok(out)
279}
280
281/// Decode the `TagList` attribute value.
282///
283/// # Errors
284/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
285pub fn decode_tag_list(tlv: &[u8]) -> Result<Vec<SemanticTagStruct>, ClusterError> {
286    let mut r = TlvReader::new(tlv);
287    match r.next()? {
288        Some(Element::ContainerStart {
289            kind: ContainerKind::Array,
290            ..
291        }) => {}
292        _ => return Err(ClusterError::UnexpectedType { context: "TagList" }),
293    }
294    let r = &mut r;
295    let mut out = Vec::new();
296    loop {
297        match r.next()? {
298            Some(Element::ContainerEnd) => break,
299            Some(Element::ContainerStart {
300                kind: ContainerKind::Structure,
301                ..
302            }) => {
303                out.push(SemanticTagStruct::decode_from(r)?);
304            }
305            None => return Err(ClusterError::Tlv(matter_codec::Error::UnclosedContainer)),
306            Some(Element::ContainerStart { .. }) => r.skip_container()?,
307            Some(_) => {} // skip unknown scalar
308        }
309    }
310    Ok(out)
311}
312
313/// Decode the `EndpointUniqueId` attribute value.
314///
315/// # Errors
316/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
317pub fn decode_endpoint_unique_id(tlv: &[u8]) -> Result<String, ClusterError> {
318    let mut r = TlvReader::new(tlv);
319    match r.next()? {
320        Some(Element::Scalar {
321            value: Value::Utf8(v),
322            ..
323        }) => Ok(v),
324        _ => Err(ClusterError::UnexpectedType {
325            context: "EndpointUniqueId",
326        }),
327    }
328}