Skip to main content

rs_matter/tlv/
read.rs

1/*
2 *
3 *    Copyright (c) 2024-2026 Project CHIP Authors
4 *
5 *    Licensed under the Apache License, Version 2.0 (the "License");
6 *    you may not use this file except in compliance with the License.
7 *    You may obtain a copy of the License at
8 *
9 *        http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *    Unless required by applicable law or agreed to in writing, software
12 *    distributed under the License is distributed on an "AS IS" BASIS,
13 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *    See the License for the specific language governing permissions and
15 *    limitations under the License.
16 */
17
18use core::{cmp::Ordering, fmt};
19
20use crate::error::{Error, ErrorCode};
21
22use super::{pad, FromTLV, TLVControl, TLVTag, TLVTagType, TLVValue, TLVValueType, TLV};
23
24/// A newtype for reading TLV-encoded data from Rust `&[u8]` slices.
25///
26/// Semantically, a `TLVElement` is just a byte slice of TLV-encoded data/stream, and the methods provided by this therefore
27/// allow to parse - on the fly - the byte slice as TLV.
28///
29/// Note also, that - as per the Matter Core Spec:
30/// - A valid TLV stream always represents a SINGLE TLV element (hence why this type is named `TLVElement` and why we claim
31///   that it represents also a whole TLV stream)
32/// - If there is a need to encode more than one TLV element, they should be encoded in a TLV container (array, list or struct),
33///   hence we end up again with a single TLV element, which represents the whole container.
34///
35/// Parsing/reading/validating the TLV of the slice represented by a `TLVElement` is done on-demand. What this means is that:
36/// - `TLVElement::new(slice)` always succeeds, even when the passed slice contains invalid TLV data
37/// - As the various methods of `TLVElement` type are called, the data in the slice is parsed and validated on the fly. Hence why all methods
38///   on `TLVElement` except `is_empty` are fallible.
39///
40/// A TLV element can currently be constructed from an empty `&[]` slice, but the empty slice does not actually represent a TLV element,
41/// so all methods except `TLVElement::is_empty` would fail on a `TLVElement` constructed from an empty slice. The only reason why empty slices
42/// are currently allowed is to simplify the `FromTLV` trait a bit by representing data which was not found (i.e. optional data in TLV structures)
43/// as a TLVElement with an empty slice.
44///
45/// The design approach from above (on-demand parsing/validation) trades memory efficiency for extra computations, in that by simply decorating
46/// a Rust `&[u8]` slice anbd post-poning everything else post-construction it ensures the size of a `TLVElement` is equal to the size of the wrapped
47/// `&[u8]` slice - i.e., a regular Rust fat pointer (8 bytes on 32 bit archs and 16 bytes on 64 bit archs).
48///
49/// Furthermore, all accompanying types of `TLVElement`, like `TLVSequence`, `TLVContainerIter` and `TLVArray` are also just newtypes over byte slices
50/// and therefore just as small.
51///
52/// (Keeping interim data is still optionally possible, by using the `TLV::tag` and `TLV::value`
53/// methods to read the tag and value of a TLV as enums.)
54///
55/// As for representing the encoded TLV stream itself as a raw `&[u8]` slice - this trivializes the traversal of the stream
56/// as the stream traversal is represented as returning sub-slices of the original slice. It also allows `FromTLV` implementations where
57/// the data is borrowed directly from the `&[u8]` slice representing the encoded TLV stream without any data moves. Types that implement
58/// such borrowing are e.g.:
59/// - `&str` (used to represent borrowed TLV UTF-8 strings)
60/// - `Bytes<'a>` (a newtype over `&'a [u8]` - used to represent TLV octet strings)
61/// - `TLVArray`
62/// - `TLVSequence` - discussed below
63///
64/// Also, this representation naturally allows random-access to the TLV stream, which is necessary for a number of reasons:
65/// - Deserialization of TLV structs into Rust structs (with the `FromTLV` derive macro) where the order of the TLV elements
66///   of the struct is not known in advance
67/// - Delayed in-place initialization of large Rust types with `FromTLV::init_from_tlv` which requires random access for reasons
68///   beyond the possible unordering of the TLV struct elements.
69///
70/// In practice, random access - and in general - representation of the TLV stream as a `&[u8]` slice should be natural and
71/// convenient, as the TLV stream usually comes from the network UDP/TCP memory buffers of the Matter transport protocol, and
72/// these can and are borrowed as `&[u8]` slices in the upper-layer code for direct reads.
73#[derive(Clone, PartialEq, Eq, Hash)]
74#[repr(transparent)]
75pub struct TLVElement<'a>(TLVSequence<'a>);
76
77impl<'a> TLVElement<'a> {
78    /// Read a mandatory context-tagged field out of this (structure) element.
79    ///
80    /// Taking the tag as a runtime argument rather than baking it into the
81    /// caller is what keeps this cheap in code size: the generated per-field
82    /// accessors are otherwise structurally identical yet monomorphise
83    /// separately, so the same TLV walk is emitted once per *field* instead of
84    /// once per *type*.
85    pub fn read<T: FromTLV<'a>>(&self, ctx: u8) -> Result<T, Error> {
86        T::from_tlv(&self.structure()?.ctx(ctx)?)
87    }
88
89    /// Read an optional context-tagged field out of this (structure) element.
90    ///
91    /// Returns `None` when the field is absent. See [`Self::read`] for why the
92    /// tag is a runtime argument.
93    pub fn read_opt<T: FromTLV<'a>>(&self, ctx: u8) -> Result<Option<T>, Error> {
94        let element = self.structure()?.find_ctx(ctx)?;
95
96        if element.is_empty() {
97            Ok(None)
98        } else {
99            Ok(Some(T::from_tlv(&element)?))
100        }
101    }
102
103    /// Create a new `TLVElement` from a byte slice, where the byte slice contains an encoded TLV stream (a TLV element).
104    #[inline(always)]
105    pub const fn new(data: &'a [u8]) -> Self {
106        Self(TLVSequence(data))
107    }
108
109    /// Return `true` if the wrapped byte slice is the empty `&[]` slice.
110    /// Empty byte slices do not represent valid TLV data, as the TLV data should be a valid TLV element,
111    /// yet they are useful when implementing the `FromTLV` trait.
112    #[inline(always)]
113    pub fn is_empty(&self) -> bool {
114        self.0 .0.is_empty()
115    }
116
117    /// Return `Some(self)` if the wrapped byte slice is not empty, `None` otherwise.
118    pub fn non_empty(&self) -> Option<&TLVElement<'a>> {
119        if self.is_empty() {
120            None
121        } else {
122            Some(self)
123        }
124    }
125
126    /// Return a copy of the wrapped TLV byte slice.
127    #[inline(always)]
128    pub const fn raw_data(&self) -> &'a [u8] {
129        self.0 .0
130    }
131
132    /// Return the TLV control byte of the first TLV in the slice.
133    ///
134    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the first byte of the slice does
135    /// not represent a valid TLV control byte or if the wrapped byte slice is empty.
136    #[inline(always)]
137    pub fn control(&self) -> Result<TLVControl, Error> {
138        self.0.control()
139    }
140
141    /// Return a sub-slice of the wrapped byte slice that designates the encoded value
142    /// of this `TLVElement` (i.e. the raw "value" aspect of the Tag-Length-Value encoding)
143    ///
144    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
145    /// contains malformed TLV data.
146    ///
147    /// For getting a parsed value, use `value` or any of the other helper methods that
148    /// retrieve a value of a certain type.
149    #[inline(always)]
150    pub fn raw_value(&self) -> Result<&'a [u8], Error> {
151        self.0.raw_value()
152    }
153
154    /// Return a `TLV` struct representing the tag and value of this `TLVElement`.
155    /// This method is a convenience method that combines the `tag` and `value` methods.
156    pub fn tlv(&self) -> Result<TLV<'a>, Error> {
157        Ok(TLV {
158            tag: self.tag()?,
159            value: self.value()?,
160        })
161    }
162
163    /// Return a `TLVTag` enum representing the tag of this `TLVElement`.
164    ///
165    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV
166    /// byte slice contains malformed TLV data.
167    #[inline(always)]
168    pub fn tag(&self) -> Result<TLVTag, Error> {
169        let tag_type = self.control()?.tag_type;
170
171        let slice = self
172            .0
173            .tag_start()?
174            .get(..tag_type.size())
175            .ok_or(ErrorCode::TLVTypeMismatch)?;
176
177        let tag = match tag_type {
178            TLVTagType::Anonymous => TLVTag::Anonymous,
179            TLVTagType::Context => TLVTag::Context(slice[0]),
180            TLVTagType::CommonPrf16 => {
181                TLVTag::CommonPrf16(u16::from_le_bytes(unwrap!(slice.try_into())))
182            }
183            TLVTagType::CommonPrf32 => {
184                TLVTag::CommonPrf32(u32::from_le_bytes(unwrap!(slice.try_into())))
185            }
186            TLVTagType::ImplPrf16 => {
187                TLVTag::ImplPrf16(u16::from_le_bytes(unwrap!(slice.try_into())))
188            }
189            TLVTagType::ImplPrf32 => {
190                TLVTag::ImplPrf32(u32::from_le_bytes(unwrap!(slice.try_into())))
191            }
192            TLVTagType::FullQual48 => TLVTag::FullQual48 {
193                vendor_id: u16::from_le_bytes([slice[0], slice[1]]),
194                profile: u16::from_le_bytes([slice[2], slice[3]]),
195                tag: u16::from_le_bytes([slice[4], slice[5]]),
196            },
197            TLVTagType::FullQual64 => TLVTag::FullQual64 {
198                vendor_id: u16::from_le_bytes([slice[0], slice[1]]),
199                profile: u16::from_le_bytes([slice[2], slice[3]]),
200                tag: u32::from_le_bytes([slice[4], slice[5], slice[6], slice[7]]),
201            },
202        };
203
204        Ok(tag)
205    }
206
207    /// Return a `TLVValue` enum representing the value of this `TLVElement`.
208    ///
209    /// Note that if the TLV element is a container, the return `TLV` value would only deisgnate
210    /// the container type (struct, array or list) and not the actual content of the container.
211    pub fn value(&self) -> Result<TLVValue<'a>, Error> {
212        let control = self.control()?;
213
214        let slice = self.0.container_value(control)?;
215
216        let value = match control.value_type {
217            TLVValueType::S8 => TLVValue::S8(i8::from_le_bytes(unwrap!(slice.try_into()))),
218            TLVValueType::S16 => TLVValue::S16(i16::from_le_bytes(unwrap!(slice.try_into()))),
219            TLVValueType::S32 => TLVValue::S32(i32::from_le_bytes(unwrap!(slice.try_into()))),
220            TLVValueType::S64 => TLVValue::S64(i64::from_le_bytes(unwrap!(slice.try_into()))),
221            TLVValueType::U8 => TLVValue::U8(u8::from_le_bytes(unwrap!(slice.try_into()))),
222            TLVValueType::U16 => TLVValue::U16(u16::from_le_bytes(unwrap!(slice.try_into()))),
223            TLVValueType::U32 => TLVValue::U32(u32::from_le_bytes(unwrap!(slice.try_into()))),
224            TLVValueType::U64 => TLVValue::U64(u64::from_le_bytes(unwrap!(slice.try_into()))),
225            TLVValueType::False => TLVValue::False,
226            TLVValueType::True => TLVValue::True,
227            TLVValueType::F32 => TLVValue::F32(f32::from_le_bytes(unwrap!(slice.try_into()))),
228            TLVValueType::F64 => TLVValue::F64(f64::from_le_bytes(unwrap!(slice.try_into()))),
229            TLVValueType::Utf8l => TLVValue::Utf8l(
230                core::str::from_utf8(slice).map_err(|_| ErrorCode::TLVTypeMismatch)?,
231            ),
232            TLVValueType::Utf16l => TLVValue::Utf16l(
233                core::str::from_utf8(slice).map_err(|_| ErrorCode::TLVTypeMismatch)?,
234            ),
235            TLVValueType::Utf32l => TLVValue::Utf32l(
236                core::str::from_utf8(slice).map_err(|_| ErrorCode::TLVTypeMismatch)?,
237            ),
238            TLVValueType::Utf64l => TLVValue::Utf64l(
239                core::str::from_utf8(slice).map_err(|_| ErrorCode::TLVTypeMismatch)?,
240            ),
241            TLVValueType::Str8l => TLVValue::Str8l(slice),
242            TLVValueType::Str16l => TLVValue::Str16l(slice),
243            TLVValueType::Str32l => TLVValue::Str32l(slice),
244            TLVValueType::Str64l => TLVValue::Str64l(slice),
245            TLVValueType::Null => TLVValue::Null,
246            TLVValueType::Struct => TLVValue::Struct,
247            TLVValueType::Array => TLVValue::Array,
248            TLVValueType::List => TLVValue::List,
249            TLVValueType::EndCnt => TLVValue::EndCnt,
250        };
251
252        Ok(value)
253    }
254
255    /// Return the value of this TLV element as an `i8`.
256    ///
257    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
258    /// contains malformed TLV data.
259    ///
260    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
261    /// a TLV S8 value.
262    pub fn i8(&self) -> Result<i8, Error> {
263        let control = self.control()?;
264
265        if matches!(control.value_type, TLVValueType::S8) {
266            Ok(i8::from_le_bytes(
267                self.0
268                    .value(control)?
269                    .try_into()
270                    .map_err(|_| ErrorCode::InvalidData)?,
271            ))
272        } else {
273            Err(ErrorCode::TLVTypeMismatch.into())
274        }
275    }
276
277    /// Return the value of this TLV element as a `u8`.
278    ///
279    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
280    /// contains malformed TLV data.
281    ///
282    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
283    /// a TLV U8 value.
284    pub fn u8(&self) -> Result<u8, Error> {
285        let control = self.control()?;
286
287        if matches!(control.value_type, TLVValueType::U8) {
288            Ok(u8::from_le_bytes(
289                self.0
290                    .value(control)?
291                    .try_into()
292                    .map_err(|_| ErrorCode::InvalidData)?,
293            ))
294        } else {
295            Err(ErrorCode::TLVTypeMismatch.into())
296        }
297    }
298
299    /// Return the value of this TLV element as an `i16`.
300    ///
301    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
302    /// contains malformed TLV data.
303    ///
304    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
305    /// a TLV S8 or S16 value.
306    pub fn i16(&self) -> Result<i16, Error> {
307        let control = self.control()?;
308
309        if matches!(control.value_type, TLVValueType::S16) {
310            Ok(i16::from_le_bytes(
311                self.0
312                    .value(control)?
313                    .try_into()
314                    .map_err(|_| ErrorCode::InvalidData)?,
315            ))
316        } else {
317            self.i8().map(|a| a.into())
318        }
319    }
320
321    /// Return the value of this TLV element as a `u16`.
322    ///
323    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
324    /// contains malformed TLV data.
325    ///
326    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
327    /// a TLV U8 or U16 value.
328    pub fn u16(&self) -> Result<u16, Error> {
329        let control = self.control()?;
330
331        if matches!(control.value_type, TLVValueType::U16) {
332            Ok(u16::from_le_bytes(
333                self.0
334                    .value(control)?
335                    .try_into()
336                    .map_err(|_| ErrorCode::InvalidData)?,
337            ))
338        } else {
339            self.u8().map(|a| a.into())
340        }
341    }
342
343    /// Return the value of this TLV element as an `i32`.
344    ///
345    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
346    /// contains malformed TLV data.
347    ///
348    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
349    /// a TLV S8, S16 or S32 value.
350    pub fn i32(&self) -> Result<i32, Error> {
351        let control = self.control()?;
352
353        if matches!(control.value_type, TLVValueType::S32) {
354            Ok(i32::from_le_bytes(
355                self.0
356                    .value(control)?
357                    .try_into()
358                    .map_err(|_| ErrorCode::InvalidData)?,
359            ))
360        } else {
361            self.i16().map(|a| a.into())
362        }
363    }
364
365    /// Return the value of this TLV element as a `u32`.
366    ///
367    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
368    /// contains malformed TLV data.
369    ///
370    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
371    /// a TLV U8, U16 or U32 value.
372    pub fn u32(&self) -> Result<u32, Error> {
373        let control = self.control()?;
374
375        if matches!(control.value_type, TLVValueType::U32) {
376            Ok(u32::from_le_bytes(
377                self.0
378                    .value(control)?
379                    .try_into()
380                    .map_err(|_| ErrorCode::InvalidData)?,
381            ))
382        } else {
383            self.u16().map(|a| a.into())
384        }
385    }
386
387    /// Return the value of this TLV element as an `i64`.
388    ///
389    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
390    /// contains malformed TLV data.
391    ///
392    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
393    /// a TLV S8, S16, S32 or S64 value.
394    pub fn i64(&self) -> Result<i64, Error> {
395        let control = self.control()?;
396
397        if matches!(control.value_type, TLVValueType::S64) {
398            Ok(i64::from_le_bytes(
399                self.0
400                    .value(control)?
401                    .try_into()
402                    .map_err(|_| ErrorCode::InvalidData)?,
403            ))
404        } else {
405            self.i32().map(|a| a.into())
406        }
407    }
408
409    /// Return the value of this TLV element as a `u64`.
410    ///
411    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
412    /// contains malformed TLV data.
413    ///
414    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
415    /// a TLV U8, U16, U32 or U64 value.
416    pub fn u64(&self) -> Result<u64, Error> {
417        let control = self.control()?;
418
419        if matches!(control.value_type, TLVValueType::U64) {
420            Ok(u64::from_le_bytes(
421                self.0
422                    .value(control)?
423                    .try_into()
424                    .map_err(|_| ErrorCode::InvalidData)?,
425            ))
426        } else {
427            self.u32().map(|a| a.into())
428        }
429    }
430
431    /// Return the value of this TLV element as an `f32`.
432    ///
433    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
434    /// contains malformed TLV data.
435    ///
436    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
437    /// a TLV F32 value.
438    pub fn f32(&self) -> Result<f32, Error> {
439        let control = self.control()?;
440
441        if matches!(control.value_type, TLVValueType::F32) {
442            Ok(f32::from_le_bytes(
443                self.0
444                    .value(control)?
445                    .try_into()
446                    .map_err(|_| ErrorCode::InvalidData)?,
447            ))
448        } else {
449            Err(ErrorCode::TLVTypeMismatch.into())
450        }
451    }
452
453    /// Return the value of this TLV element as an `f64`.
454    ///
455    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
456    /// contains malformed TLV data.
457    ///
458    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
459    /// a TLV F64 value.
460    pub fn f64(&self) -> Result<f64, Error> {
461        let control = self.control()?;
462
463        if matches!(control.value_type, TLVValueType::F64) {
464            Ok(f64::from_le_bytes(
465                self.0
466                    .value(control)?
467                    .try_into()
468                    .map_err(|_| ErrorCode::InvalidData)?,
469            ))
470        } else {
471            Err(ErrorCode::TLVTypeMismatch.into())
472        }
473    }
474
475    /// Return the value of this TLV element as a byte slice.
476    ///
477    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
478    /// contains malformed TLV data.
479    ///
480    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
481    /// a TLV Octet String.
482    pub fn str(&self) -> Result<&'a [u8], Error> {
483        let control = self.control()?;
484
485        if !control.value_type.is_str() {
486            Err(ErrorCode::Invalid)?;
487        }
488
489        self.0.value(control)
490    }
491
492    /// Return the value of this TLV element as a UTF-8 string.
493    ///
494    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
495    /// contains malformed TLV data.
496    ///
497    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
498    /// a TLV UTF-8 String.
499    pub fn utf8(&self) -> Result<&'a str, Error> {
500        let control = self.control()?;
501
502        if !control.value_type.is_utf8() {
503            Err(ErrorCode::Invalid)?;
504        }
505
506        core::str::from_utf8(self.0.value(control)?).map_err(|_| ErrorCode::InvalidData.into())
507    }
508
509    /// Return the value of this TLV element as a UTF-16 string.
510    ///
511    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
512    /// contains malformed TLV data.
513    ///
514    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
515    /// a TLV UTF-8 String or a TLV octet string.
516    pub fn octets(&self) -> Result<&'a [u8], Error> {
517        let control = self.control()?;
518
519        if control.value_type.variable_size_len() == 0 {
520            Err(ErrorCode::Invalid)?;
521        }
522
523        self.0.value(control)
524    }
525
526    /// Return the value of this TLV element as a UTF-16 string.
527    ///
528    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
529    /// contains malformed TLV data.
530    ///
531    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
532    /// a TLV boolean.
533    pub fn bool(&self) -> Result<bool, Error> {
534        let control = self.control()?;
535
536        match control.value_type {
537            TLVValueType::False => Ok(false),
538            TLVValueType::True => Ok(true),
539            _ => Err(ErrorCode::TLVTypeMismatch.into()),
540        }
541    }
542
543    /// Return `true` if this TLV element is as a container (i.e., a struct, array or list).
544    ///
545    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
546    /// contains malformed TLV data.
547    pub fn is_container(&self) -> Result<bool, Error> {
548        Ok(self.control()?.value_type.is_container())
549    }
550
551    /// Confirm that this TLV element contains a TLV null value.
552    ///
553    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
554    /// contains malformed TLV data.
555    ///
556    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
557    /// a TLV null value.
558    pub fn null(&self) -> Result<(), Error> {
559        if matches!(self.control()?.value_type, TLVValueType::Null) {
560            Ok(())
561        } else {
562            Err(ErrorCode::InvalidData.into())
563        }
564    }
565
566    /// Return the content of the struct container represented by this TLV element.
567    ///
568    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
569    /// contains malformed TLV data.
570    ///
571    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
572    /// a TLV struct.
573    pub fn structure(&self) -> Result<TLVSequence<'a>, Error> {
574        self.r#struct()
575    }
576
577    /// Return the content of the struct container represented by this TLV element.
578    ///
579    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
580    /// contains malformed TLV data.
581    ///
582    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
583    /// a TLV struct.
584    ///
585    /// (Same as method `structure` but with a special name to ease the `FromTLV` trait derivation for
586    /// user types.)
587    pub fn r#struct(&self) -> Result<TLVSequence<'a>, Error> {
588        if matches!(self.control()?.value_type, TLVValueType::Struct) {
589            self.0.next_enter()
590        } else {
591            Err(ErrorCode::TLVTypeMismatch.into())
592        }
593    }
594
595    /// Return the content of the array container represented by this TLV element.
596    ///
597    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
598    /// contains malformed TLV data.
599    ///
600    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
601    /// a TLV array.
602    pub fn array(&self) -> Result<TLVSequence<'a>, Error> {
603        if matches!(self.control()?.value_type, TLVValueType::Array) {
604            self.0.next_enter()
605        } else {
606            Err(ErrorCode::InvalidData.into())
607        }
608    }
609
610    /// Return the content of the list container represented by this TLV element.
611    ///
612    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
613    /// contains malformed TLV data.
614    ///
615    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
616    /// a TLV list.
617    pub fn list(&self) -> Result<TLVSequence<'a>, Error> {
618        if matches!(self.control()?.value_type, TLVValueType::List) {
619            self.0.next_enter()
620        } else {
621            Err(ErrorCode::TLVTypeMismatch.into())
622        }
623    }
624
625    /// Return the content of the container (array, struct or list) represented by this TLV element.
626    ///
627    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
628    /// contains malformed TLV data.
629    ///
630    /// Returns an error with code `ErrorCode::InvalidData` if the value of the TLV element is not
631    /// a TLV container.
632    pub fn container(&self) -> Result<TLVSequence<'a>, Error> {
633        if matches!(
634            self.control()?.value_type,
635            TLVValueType::List | TLVValueType::Array | TLVValueType::Struct
636        ) {
637            self.0.next_enter()
638        } else {
639            Err(ErrorCode::TLVTypeMismatch.into())
640        }
641    }
642
643    /// Confirm that this TLV element is tagged with the anonymous tag (`TLVTag::Anonymous`).
644    ///
645    /// Returns an error with code `ErrorCode::TLVTypeMismatch` if the wrapped TLV byte slice
646    /// contains malformed TLV data.
647    ///
648    /// Returns an error with code `ErrorCode::InvalidData` if the tag of the TLV element is not
649    /// the anonymous tag.
650    pub fn confirm_anon(&self) -> Result<(), Error> {
651        if matches!(self.control()?.tag_type, TLVTagType::Anonymous) {
652            Ok(())
653        } else {
654            Err(ErrorCode::TLVTypeMismatch.into())
655        }
656    }
657
658    /// Retrieve the context ID of the element.
659    /// If element is not tagged with a context tag, the method will return an error.
660    pub fn ctx(&self) -> Result<u8, Error> {
661        Ok(self.try_ctx()?.ok_or(ErrorCode::TLVTypeMismatch)?)
662    }
663
664    /// Retrieve the context ID of the element.
665    /// If element is not tagged with a context tag, the method will return `None`.
666    pub fn try_ctx(&self) -> Result<Option<u8>, Error> {
667        let control = self.control()?;
668
669        if matches!(control.tag_type, TLVTagType::Context) {
670            Ok(Some(
671                *self
672                    .0
673                    .tag(control.tag_type)?
674                    .first()
675                    .ok_or(ErrorCode::TLVTypeMismatch)?,
676            ))
677        } else {
678            Ok(None)
679        }
680    }
681
682    fn fmt(&self, indent: usize, f: &mut fmt::Formatter) -> fmt::Result {
683        pad(indent, f)?;
684
685        let tag = self.tag().map_err(|_| fmt::Error)?;
686
687        tag.fmt(f)?;
688
689        if !matches!(tag.tag_type(), TLVTagType::Anonymous) {
690            write!(f, ": ")?;
691        }
692
693        let value = self.value().map_err(|_| fmt::Error)?;
694
695        value.fmt(f)?;
696
697        if value.value_type().is_container() {
698            let mut empty = true;
699
700            for (index, elem) in self.container().map_err(|_| fmt::Error)?.iter().enumerate() {
701                if index > 0 {
702                    writeln!(f, ",")?;
703                } else {
704                    writeln!(f)?;
705                }
706
707                elem.map_err(|_| fmt::Error)?.fmt(indent + 2, f)?;
708
709                empty = false;
710            }
711
712            if !empty {
713                writeln!(f)?;
714                pad(indent, f)?;
715            }
716
717            match value.value_type() {
718                TLVValueType::Struct => write!(f, "}}"),
719                TLVValueType::Array => write!(f, "]"),
720                TLVValueType::List => write!(f, ")"),
721                _ => unreachable!(),
722            }?;
723        }
724
725        Ok(())
726    }
727}
728
729impl fmt::Debug for TLVElement<'_> {
730    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
731        self.fmt(0, f)
732    }
733}
734
735impl fmt::Display for TLVElement<'_> {
736    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
737        self.fmt(0, f)
738    }
739}
740
741#[cfg(feature = "defmt")]
742impl defmt::Format for TLVElement<'_> {
743    fn format(&self, f: defmt::Formatter<'_>) {
744        defmt::Display2Format(self).format(f)
745    }
746}
747
748/// A newtype for iterating over the `TLVElement` "child" instances contained in `TLVElement` which is a TLV container
749/// (array, struct or list).
750/// (Internally, `TLVSequence` might be used for other purposes, but the external contract is only the one from above.)
751///
752/// Just like `TLVElement`, `TLVSequence` is a newtype over a byte slice - the byte sub-slice of the parent `TLVElement`
753/// container where its value starts.
754///
755/// Unlike `TLVElement`, `TLVSequence` - as the name suggests - represents a sequence of 0, 1 or more `TLVElements`.
756/// The only public API of `TLVSequence` however is the `iter` method which returns a `TLVContainerIter` iterator over
757/// the `TLVElement` instances in the sequence.
758#[derive(Clone, PartialEq, Eq, Hash)]
759#[repr(transparent)]
760pub struct TLVSequence<'a>(pub(crate) &'a [u8]);
761
762impl<'a> TLVSequence<'a> {
763    const EMPTY: Self = Self(&[]);
764
765    /// Return an iterator over the `TLVElement` instances in this `TLVSequence`.
766    #[inline(always)]
767    pub fn iter(&self) -> TLVSequenceIter<'a> {
768        TLVSequenceIter::new(self.clone())
769    }
770
771    /// Return an iterator over the `TLV` instances in this `TLVSequence`.
772    ///
773    /// The difference with `iter` is that for container elements, `tlv_iter`
774    /// will return separate `TLV` instances for the container start, the container
775    /// elements and the container end, where if an element in the container is
776    /// itself a container, the algorithm will be applied recursively to the inner container.
777    pub fn tlv_iter(&self) -> TLVSequenceTLVIter<'a> {
778        TLVSequenceTLVIter::new(self.clone())
779    }
780
781    /// A convenience utility that returns the first `TLVElement` in the sequence
782    /// which is tagged with a context tag (`TLVTag::Context`) where the context ID
783    /// is matching the ID passed in the `ctx` parameter.
784    ///
785    /// If there is no TLV element tagged with a context tag with the matching ID, the method
786    /// will return an error.
787    pub fn ctx(&self, ctx: u8) -> Result<TLVElement<'a>, Error> {
788        let element = self.find_ctx(ctx)?;
789
790        if element.is_empty() {
791            Err(ErrorCode::NotFound.into())
792        } else {
793            Ok(element)
794        }
795    }
796
797    /// A convenience utility that returns the first `TLVElement` in the sequence
798    /// which is tagged with a context tag (`TLVTag::Context`) where the context ID
799    /// is matching the ID passed in the `ctx` parameter.
800    ///
801    /// If there is no TLV element tagged with a context tag with the matching ID, the method
802    /// will return an empty `TLVElement`.
803    pub fn find_ctx(&self, ctx: u8) -> Result<TLVElement<'a>, Error> {
804        for elem in self.iter() {
805            let elem = elem?;
806
807            if let Some(elem_ctx) = elem.try_ctx()? {
808                if elem_ctx == ctx {
809                    return Ok(elem);
810                }
811            }
812        }
813
814        Ok(TLVElement(Self::EMPTY))
815    }
816
817    /// A convenience utility that returns the first `TLVElement` in the sequence
818    /// which is tagged with a context tag (`TLVTag::Context`) where the context ID
819    /// is equal to the ID passed in the `ctx` parameter.
820    ///
821    /// If there is no TLV element tagged with a context tag with the matching ID, the method
822    /// will return an empty TLV element.
823    ///
824    /// As a side effect of calling this method, the `TLVSequence` instance will be updated
825    /// to point to the next element after the found element, or if an element with the
826    /// provided context ID does not exist, to the first element with a bigger context ID than
827    /// the one we are looking for.
828    pub fn scan_ctx(&mut self, ctx: u8) -> Result<TLVElement<'a>, Error> {
829        self.scan_map(move |elem| {
830            if elem.is_empty() {
831                return Ok(Some(elem));
832            }
833
834            if let Some(elem_ctx) = elem.try_ctx()? {
835                match elem_ctx.cmp(&ctx) {
836                    Ordering::Equal => return Ok(Some(elem)),
837                    Ordering::Greater => return Ok(Some(TLVElement(Self::EMPTY))),
838                    _ => (),
839                }
840            }
841
842            Ok(None)
843        })
844    }
845
846    /// A convenience utility that returns scans the elements in the sequence,
847    /// in-order and stops scanning once the provided mapping closure `f`
848    /// returns a non-empty result.
849    ///
850    /// As a side effect of calling this method, the `TLVSequence` instance will be updated
851    /// to point to the next element after the one on which the provided closure
852    /// returned a non-empty result.
853    ///
854    /// Note that the closure _must_ ultimately return a non-empty result - if for nothing else
855    /// then for the empty element that is passed to it when the sequence is exhausted,
856    /// or else the method would loop forever.
857    pub fn scan_map<F, T>(&mut self, mut f: F) -> Result<T, Error>
858    where
859        F: FnMut(TLVElement<'a>) -> Result<Option<T>, Error>,
860    {
861        loop {
862            if let Some(elem) = f(self.current()?)? {
863                return Ok(elem);
864            }
865
866            *self = self.container_next()?;
867        }
868    }
869
870    /// Return a raw byte sub-slice representing the TLV-encoded elements and only those
871    /// elements that belong to the TLV container whose elements are represented by this `TLVSequence` instance.
872    ///
873    /// This method is necessary, because both `TLVElement` instances, as well as `TLVSequence` instances - for optimization purposes -
874    /// might be constructed during iteration on slices which are technically longer than the actual TLV-encoded data
875    /// they represent.
876    ///
877    /// So in case the user is need of the actual, exact raw representation of a TLV container **value**, this method is provided.
878    #[inline(always)]
879    pub fn raw_value(&self) -> Result<&'a [u8], Error> {
880        let control = self.control()?;
881
882        self.container_value(control)
883    }
884
885    /// Return a sub-sequence representing the TLV-encoded elements after the first one on the sequence.
886    ///
887    /// As the name suggests, if the first TLV element in the sequence is a container, this method will return a sub-sequence
888    /// which corresponds to the first element INSIDE the container.
889    ///
890    /// If the sequence is empty, or the sequence contains just one element, the method will return an empty `TLVSequence`.
891    ///
892    /// Note also that this method will also return sub-sequences where the first element might be a TLV `TLVValueType::EndCnt` marker,
893    /// which - formally speaking - is not a TLVElement, but a TLV control byte that marks the end of a container.
894    fn next_enter(&self) -> Result<Self, Error> {
895        if self.0.is_empty() {
896            return Ok(Self::EMPTY);
897        }
898
899        let control = self.control()?;
900
901        Ok(Self(self.next_start(control)?))
902    }
903
904    /// Return a sub-sequence representing the TLV-encoded elements after the first one on the sequence.
905    ///
906    /// As the name suggests, if the first TLV element in the sequence is a container, this method will return a sub-sequence
907    /// which corresponds to the elements AFTER the container element (i.e., the method "skips over" the elements of the container element).
908    ///
909    /// If the sequence is empty or the sequence starts with a container-end control byte, the method will return the current sequence.
910    fn container_next(&self) -> Result<Self, Error> {
911        if self.0.is_empty() {
912            return Ok(Self::EMPTY);
913        }
914
915        let control = self.control()?;
916
917        if control.value_type.is_container_end() {
918            control.confirm_container_end()?;
919
920            return Ok(self.clone());
921        }
922
923        let mut next = self.next_enter()?;
924
925        if control.value_type.is_container() {
926            let mut level = 1;
927
928            while level > 0 {
929                let control = next.control()?;
930
931                if control.value_type.is_container_end() {
932                    control.confirm_container_end()?;
933                    level -= 1;
934                } else if control.value_type.is_container() {
935                    level += 1;
936                }
937
938                next = next.next_enter()?;
939            }
940        }
941
942        Ok(next)
943    }
944
945    /// Return the first TLV element in the sequence.
946    /// If the sequence is empty, or if the sequence starts with a container-end TLV,
947    /// an empty element will be returned.
948    fn current(&self) -> Result<TLVElement<'a>, Error> {
949        if self.0.is_empty() {
950            return Ok(TLVElement(Self::EMPTY));
951        }
952
953        let control = self.control()?;
954
955        if control.value_type.is_container_end() {
956            control.confirm_container_end()?;
957
958            return Ok(TLVElement(Self::EMPTY));
959        }
960
961        Ok(TLVElement::new(self.0))
962    }
963
964    /// Return the TLV control byte of the first TLV in the sequence.
965    /// If the sequence is empty, an error will be returned.
966    #[inline(always)]
967    fn control(&self) -> Result<TLVControl, Error> {
968        TLVControl::parse(*self.0.first().ok_or(ErrorCode::TLVTypeMismatch)?)
969    }
970
971    /// Return a sub-slice of the wrapped byte slice that designates the START of the tag payload
972    /// of the first TLV in the sequence.
973    ///
974    /// If there is no tag payload (i.e., the tag is of type `TLVTagType::Anonymous`), the returned sub-slice
975    /// will designate the start of the TLV element value or value length.
976    #[inline(always)]
977    fn tag_start(&self) -> Result<&'a [u8], Error> {
978        Ok(self.0.get(1..).ok_or(ErrorCode::TLVTypeMismatch)?)
979    }
980
981    /// Return a sub-slice of the wrapped byte slice that designates the exact raw slice representing the tag payload
982    /// of the first TLV in the sequence.
983    ///
984    /// If there is no tag payload (i.e., the tag is of type `TLVTagType::Anonymous`), the returned sub-slice
985    /// will be the empty slice.
986    #[inline(always)]
987    fn tag(&self, tag_type: TLVTagType) -> Result<&'a [u8], Error> {
988        Ok(self
989            .tag_start()?
990            .get(..tag_type.size())
991            .ok_or(ErrorCode::TLVTypeMismatch)?)
992    }
993
994    /// Return a sub-slice of the wrapped byte slice that designates the START of the value length field
995    /// of the first TLV in the sequence.
996    ///
997    /// The value length field is the field that designates the length of the value of the TLV element.
998    /// If the TLV element control byte designates an element with a fixed size or a container element,
999    /// the returned sub-slice will designate the start of the value field.
1000    #[inline(always)]
1001    fn value_len_start(&self, tag_type: TLVTagType) -> Result<&'a [u8], Error> {
1002        Ok(unwrap!(self.tag_start())
1003            .get(tag_type.size()..)
1004            .ok_or(ErrorCode::TLVTypeMismatch)?)
1005    }
1006
1007    /// Return a sub-slice of the wrapped byte slice that designates the START of the value field of
1008    /// the first TLV in the sequence.
1009    ///
1010    /// The value field is the field that designates the actual value of the TLV element.
1011    #[inline(always)]
1012    fn value_start(&self, control: TLVControl) -> Result<&'a [u8], Error> {
1013        Ok(self
1014            .value_len_start(control.tag_type)?
1015            .get(control.value_type.variable_size_len()..)
1016            .ok_or(ErrorCode::TLVTypeMismatch)?)
1017    }
1018
1019    /// Return a sub-slice of the wrapped byte slice that designates the exact raw slice representing the value payload
1020    /// of the first TLV element in the sequence.
1021    ///
1022    /// For container elements, this method will return the empty slice. Use `container_value` (a more computationally expensive method)
1023    /// to get the exact taw slice of the first TLV element value that also works for containers.
1024    #[inline(always)]
1025    fn value(&self, control: TLVControl) -> Result<&'a [u8], Error> {
1026        let value_len = self.value_len(control)?;
1027
1028        Ok(self
1029            .value_start(control)?
1030            .get(..value_len)
1031            .ok_or(ErrorCode::TLVTypeMismatch)?)
1032    }
1033
1034    /// Return a sub-slice of the wrapped byte slice that designates the exact raw slice representing the value payload
1035    /// of the first TLV element in the sequence.
1036    #[inline(always)]
1037    fn container_value(&self, control: TLVControl) -> Result<&'a [u8], Error> {
1038        let value_len = self.container_value_len(control)?;
1039
1040        Ok(self
1041            .value_start(control)?
1042            .get(..value_len)
1043            .ok_or(ErrorCode::TLVTypeMismatch)?)
1044    }
1045
1046    /// Return the length of the value field of the first TLV element in the sequence.
1047    ///
1048    /// - For elements that do have a fixed size, the fixed size will be returned.
1049    /// - For UTF-8 and octet strings, the actual string length will be returned.
1050    /// - For containers, a length of 0 will be returned. Use `container_value_len`
1051    ///   (much more computationally expensive method) to get the exact length of the container.
1052    #[inline(always)]
1053    fn value_len(&self, control: TLVControl) -> Result<usize, Error> {
1054        if let Some(fixed_size) = control.value_type.fixed_size() {
1055            return Ok(fixed_size);
1056        }
1057
1058        let size_len = control.value_type.variable_size_len();
1059
1060        let value_len_slice = self
1061            .value_len_start(control.tag_type)?
1062            .get(..size_len)
1063            .ok_or(ErrorCode::TLVTypeMismatch)?;
1064
1065        let len = match size_len {
1066            1 => u8::from_be_bytes(unwrap!(value_len_slice.try_into())) as usize,
1067            2 => u16::from_le_bytes(unwrap!(value_len_slice.try_into())) as usize,
1068            4 => u32::from_le_bytes(unwrap!(value_len_slice.try_into())) as usize,
1069            8 => u64::from_le_bytes(unwrap!(value_len_slice.try_into())) as usize,
1070            _ => unreachable!(),
1071        };
1072
1073        Ok(len)
1074    }
1075
1076    /// Return the length of the value field of the first TLV element in the sequence, regardless of the
1077    /// element type (fixed size, variable size, or container).
1078    #[inline(always)]
1079    fn container_value_len(&self, control: TLVControl) -> Result<usize, Error> {
1080        if control.value_type.is_container() {
1081            let mut next = self.clone();
1082            let mut len = 0;
1083            let mut level = 1;
1084
1085            while level > 0 {
1086                next = next.next_enter()?;
1087                len += next.len()?;
1088
1089                let control = next.control()?;
1090
1091                if control.value_type.is_container_end() {
1092                    control.confirm_container_end()?;
1093                    level -= 1;
1094                } else if control.value_type.is_container() {
1095                    level += 1;
1096                }
1097            }
1098
1099            Ok(len)
1100        } else {
1101            self.value_len(control)
1102        }
1103    }
1104
1105    /// Return the length of the first TLV element in the sequence.
1106    ///
1107    /// For containers, the return length will NOT include the elements contained inside
1108    /// the container, nor the one-byte `EndCnt` marker.
1109    #[inline(always)]
1110    fn len(&self) -> Result<usize, Error> {
1111        let control = self.control()?;
1112
1113        self.value_len(control).map(|value_len| {
1114            1 + control.tag_type.size() + control.value_type.variable_size_len() + value_len
1115        })
1116    }
1117
1118    /// Return the length of the first TLV element in the sequence, regardless of the element type.
1119    #[inline(always)]
1120    pub(crate) fn container_len(&self) -> Result<usize, Error> {
1121        let control = self.control()?;
1122
1123        self.container_value_len(control).map(|value_len| {
1124            1 + control.tag_type.size() + control.value_type.variable_size_len() + value_len
1125        })
1126    }
1127
1128    /// Returns a sub-slice representing the start of the next TLV element in the sequence.
1129    /// If the sequence contains just one element, the method will return an empty slice.
1130    /// If the sequence contains no elements, the method will return an error with code `ErrorCode::TLVTypeMismatch`.
1131    ///
1132    /// Just like `next_enter` (wich is based on `next_start`) this method does "enter" container elements,
1133    /// and might return a sub-slice where the first element is the special `EndCnt` marker.
1134    #[inline(always)]
1135    fn next_start(&self, control: TLVControl) -> Result<&'a [u8], Error> {
1136        let value_len = self.value_len(control)?;
1137
1138        Ok(self
1139            .value_start(control)?
1140            .get(value_len..)
1141            .ok_or(ErrorCode::TLVTypeMismatch)?)
1142    }
1143
1144    pub(crate) fn fmt(&self, indent: usize, f: &mut fmt::Formatter) -> fmt::Result {
1145        let mut first = true;
1146
1147        for elem in self.iter() {
1148            if first {
1149                first = false;
1150            } else {
1151                writeln!(f, ",")?;
1152            }
1153
1154            let elem = elem.map_err(|_| fmt::Error)?;
1155
1156            elem.fmt(indent, f)?;
1157        }
1158
1159        if !first {
1160            writeln!(f)?;
1161        }
1162
1163        Ok(())
1164    }
1165}
1166
1167impl fmt::Debug for TLVSequence<'_> {
1168    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1169        self.fmt(0, f)
1170    }
1171}
1172
1173impl fmt::Display for TLVSequence<'_> {
1174    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1175        self.fmt(0, f)
1176    }
1177}
1178
1179#[cfg(feature = "defmt")]
1180impl defmt::Format for TLVSequence<'_> {
1181    fn format(&self, f: defmt::Formatter<'_>) {
1182        defmt::Display2Format(self).format(f)
1183    }
1184}
1185
1186/// A type representing an iterator over the elements of a `TLVSequence` returning `TLV` instances.
1187#[derive(Clone)]
1188pub struct TLVSequenceTLVIter<'a> {
1189    seq: TLVSequence<'a>,
1190    nesting: usize,
1191}
1192
1193impl<'a> TLVSequenceTLVIter<'a> {
1194    /// Create a new `TLVContainerIter` instance.
1195    const fn new(seq: TLVSequence<'a>) -> Self {
1196        Self { seq, nesting: 0 }
1197    }
1198
1199    fn try_next(&mut self) -> Result<Option<TLV<'a>>, Error> {
1200        let current = self.seq.current()?;
1201        if current.is_empty() {
1202            return Ok(None);
1203        }
1204
1205        self.advance()?;
1206
1207        Ok(Some(TLV::new(current.tag()?, current.value()?)))
1208    }
1209
1210    fn advance(&mut self) -> Result<(), Error> {
1211        if self.nesting > 0 || !self.seq.0.is_empty() && !self.seq.control()?.is_container_end() {
1212            self.seq = self.seq.next_enter()?;
1213
1214            let control = self.seq.control()?;
1215
1216            if control.is_container_start() {
1217                self.nesting += 1;
1218            } else if control.is_container_end() {
1219                self.nesting -= 1;
1220            }
1221        }
1222
1223        Ok(())
1224    }
1225}
1226
1227impl<'a> Iterator for TLVSequenceTLVIter<'a> {
1228    type Item = Result<TLV<'a>, Error>;
1229
1230    fn next(&mut self) -> Option<Self::Item> {
1231        self.try_next().transpose()
1232    }
1233}
1234
1235/// A type representing an iterator over the elements of a `TLVSequence`.
1236#[derive(Clone)]
1237#[repr(transparent)]
1238pub struct TLVSequenceIter<'a>(TLVSequence<'a>);
1239
1240impl<'a> TLVSequenceIter<'a> {
1241    /// Create a new `TLVContainerIter` instance.
1242    const fn new(seq: TLVSequence<'a>) -> Self {
1243        Self(seq)
1244    }
1245
1246    fn advance(&mut self) -> Result<(), Error> {
1247        self.0 = self.0.container_next()?;
1248
1249        Ok(())
1250    }
1251}
1252
1253impl<'a> Iterator for TLVSequenceIter<'a> {
1254    type Item = Result<TLVElement<'a>, Error>;
1255
1256    fn next(&mut self) -> Option<Self::Item> {
1257        self.0
1258            .current()
1259            .and_then(|current| self.advance().map(|_| current))
1260            .map(|elem| (!elem.is_empty()).then_some(elem))
1261            .transpose()
1262    }
1263}
1264
1265impl fmt::Debug for TLVSequenceIter<'_> {
1266    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1267        self.0.fmt(0, f)
1268    }
1269}
1270
1271impl fmt::Display for TLVSequenceIter<'_> {
1272    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1273        self.0.fmt(0, f)
1274    }
1275}
1276
1277#[cfg(feature = "defmt")]
1278impl defmt::Format for TLVSequenceIter<'_> {
1279    fn format(&self, f: defmt::Formatter<'_>) {
1280        defmt::Display2Format(self).format(f)
1281    }
1282}
1283
1284#[cfg(test)]
1285mod tests {
1286    use core::{f32, f64};
1287
1288    use super::TLVElement;
1289    use crate::{
1290        tlv::{TLVArray, TLVList, TLVSequence, TLVStruct, TLVTag, TLVValue, TLVWrite, TLV},
1291        utils::storage::WriteBuf,
1292    };
1293
1294    #[test]
1295    fn test_no_container_for_int() {
1296        // The 0x24 is a a tagged integer, here the integer is 2
1297        let data = &[0x15, 0x24, 0x1, 0x2];
1298        let seq = TLVSequence(data);
1299        // Skip the 0x15
1300        let seq = seq.next_enter().unwrap();
1301
1302        let elem = TLVElement(seq);
1303        assert!(elem.container().is_err());
1304    }
1305
1306    #[test]
1307    fn test_struct_iteration_with_mix_values() {
1308        // This is a struct with 3 valid values
1309        let data = &[
1310            0x15, 0x24, 0x0, 0x2, 0x26, 0x2, 0x4e, 0x10, 0x02, 0x00, 0x30, 0x3, 0x04, 0x73, 0x6d,
1311            0x61, 0x72,
1312        ];
1313
1314        let mut root_iter = TLVElement::new(data).structure().unwrap().iter();
1315        assert_eq!(
1316            root_iter.next().unwrap().unwrap().tlv().unwrap(),
1317            TLV {
1318                tag: TLVTag::Context(0),
1319                value: TLVValue::U8(2),
1320            }
1321        );
1322        assert_eq!(
1323            root_iter.next().unwrap().unwrap().tlv().unwrap(),
1324            TLV {
1325                tag: TLVTag::Context(2),
1326                value: TLVValue::U32(135246),
1327            }
1328        );
1329        assert_eq!(
1330            root_iter.next().unwrap().unwrap().tlv().unwrap(),
1331            TLV {
1332                tag: TLVTag::Context(3),
1333                value: TLVValue::Str8l(&[0x73, 0x6d, 0x61, 0x72]),
1334            }
1335        );
1336    }
1337
1338    #[test]
1339    fn test_struct_find_element_mix_values() {
1340        // This is a struct with 3 valid values
1341        let data = &[
1342            0x15, 0x30, 0x3, 0x04, 0x73, 0x6d, 0x61, 0x72, 0x24, 0x0, 0x2, 0x26, 0x2, 0x4e, 0x10,
1343            0x02, 0x00,
1344        ];
1345        let root = TLVElement::new(data).structure().unwrap();
1346
1347        assert_eq!(
1348            root.find_ctx(0).unwrap().tlv().unwrap(),
1349            TLV {
1350                tag: TLVTag::Context(0),
1351                value: TLVValue::U8(2),
1352            }
1353        );
1354        assert_eq!(root.find_ctx(2).unwrap().tag().unwrap(), TLVTag::Context(2));
1355        assert_eq!(root.find_ctx(2).unwrap().u64().unwrap(), 135246);
1356
1357        assert_eq!(root.find_ctx(3).unwrap().tag().unwrap(), TLVTag::Context(3));
1358        assert_eq!(
1359            root.find_ctx(3).unwrap().str().unwrap(),
1360            &[0x73, 0x6d, 0x61, 0x72]
1361        );
1362    }
1363
1364    #[test]
1365    fn test_container_len() {
1366        let mut buf = [0; 200];
1367        let mut tw = WriteBuf::new(&mut buf);
1368
1369        tw.start_struct(&TLVTag::Context(0)).unwrap();
1370        tw.u64(&TLVTag::Context(0), 1234).unwrap();
1371        tw.u64(&TLVTag::Context(1), 1234).unwrap();
1372        tw.end_container().unwrap();
1373
1374        // container_len should exactly match the underlying slice holding the complete structure
1375        assert_eq!(tw.as_slice().len(), 11);
1376        assert_eq!(
1377            TLVSequence(tw.as_slice()).container_len().unwrap(),
1378            tw.as_slice().len()
1379        );
1380    }
1381
1382    #[test]
1383    fn test_list_iteration_with_mix_values() {
1384        // This is a list with 3 valid values
1385        let data = &[
1386            0x17, 0x24, 0x0, 0x2, 0x26, 0x2, 0x4e, 0x10, 0x02, 0x00, 0x30, 0x3, 0x04, 0x73, 0x6d,
1387            0x61, 0x72,
1388        ];
1389        let mut root_iter = TLVElement::new(data).list().unwrap().iter();
1390        assert_eq!(
1391            root_iter.next().unwrap().unwrap().tlv().unwrap(),
1392            TLV {
1393                tag: TLVTag::Context(0),
1394                value: TLVValue::U8(2),
1395            }
1396        );
1397        assert_eq!(
1398            root_iter.next().unwrap().unwrap().tlv().unwrap(),
1399            TLV {
1400                tag: TLVTag::Context(2),
1401                value: TLVValue::U32(135246),
1402            }
1403        );
1404        assert_eq!(
1405            root_iter.next().unwrap().unwrap().tlv().unwrap(),
1406            TLV {
1407                tag: TLVTag::Context(3),
1408                value: TLVValue::Str8l(&[0x73, 0x6d, 0x61, 0x72]),
1409            }
1410        );
1411    }
1412
1413    #[test]
1414    fn test_read_past_end_of_container() {
1415        let data = &[0x15, 0x35, 0x0, 0x24, 0x1, 0x2, 0x18, 0x24, 0x0, 0x2, 0x18];
1416
1417        let mut struct2_iter = TLVElement::new(data)
1418            .structure()
1419            .unwrap()
1420            .find_ctx(0)
1421            .unwrap()
1422            .structure()
1423            .unwrap()
1424            .iter();
1425
1426        assert_eq!(
1427            struct2_iter.next().unwrap().unwrap().tlv().unwrap(),
1428            TLV {
1429                tag: TLVTag::Context(1),
1430                value: TLVValue::U8(2),
1431            }
1432        );
1433        assert!(struct2_iter.next().is_none());
1434        // Call next, even after the first next returns None
1435        assert!(struct2_iter.next().is_none());
1436        assert!(struct2_iter.next().is_none());
1437    }
1438
1439    #[test]
1440    fn test_iteration() {
1441        // This is the input we have
1442        // {
1443        //   0: [
1444        //     {
1445        //       0: L[ 0: 2, 2: 6, 3: 1],
1446        //       1: {},
1447        //     },
1448        //   ],
1449        // }
1450
1451        let data = &[
1452            0x15, 0x36, 0x0, 0x15, 0x37, 0x0, 0x24, 0x0, 0x2, 0x24, 0x2, 0x6, 0x24, 0x3, 0x1, 0x18,
1453            0x35, 0x1, 0x18, 0x18, 0x18, 0x18,
1454        ];
1455
1456        let struct0 = TLVStruct::<TLVElement>::new(TLVElement::new(data)).unwrap();
1457
1458        assert_eq!(
1459            struct0.element().tlv().unwrap(),
1460            TLV {
1461                tag: TLVTag::Anonymous,
1462                value: TLVValue::Struct,
1463            }
1464        );
1465        assert_eq!(struct0.iter().count(), 1);
1466
1467        let array = TLVArray::<TLVElement>::new(struct0.iter().next().unwrap().unwrap()).unwrap();
1468
1469        assert_eq!(
1470            array.element().tlv().unwrap(),
1471            TLV {
1472                tag: TLVTag::Context(0),
1473                value: TLVValue::Array,
1474            }
1475        );
1476        assert_eq!(array.iter().count(), 1);
1477
1478        let struct1 = TLVStruct::<TLVElement>::new(array.iter().next().unwrap().unwrap()).unwrap();
1479        assert_eq!(
1480            struct1.element().tlv().unwrap(),
1481            TLV {
1482                tag: TLVTag::Anonymous,
1483                value: TLVValue::Struct,
1484            }
1485        );
1486        assert_eq!(struct1.iter().count(), 2);
1487
1488        let mut struct1_iter = struct1.iter();
1489
1490        let list = TLVList::<TLVElement>::new(struct1_iter.next().unwrap().unwrap()).unwrap();
1491        assert_eq!(
1492            list.element().tlv().unwrap(),
1493            TLV {
1494                tag: TLVTag::Context(0),
1495                value: TLVValue::List,
1496            }
1497        );
1498        assert_eq!(list.iter().count(), 3);
1499
1500        let mut list_iter = list.iter();
1501
1502        let le1 = list_iter.next().unwrap().unwrap();
1503        assert_eq!(
1504            le1.tlv().unwrap(),
1505            TLV {
1506                tag: TLVTag::Context(0),
1507                value: TLVValue::U8(2)
1508            }
1509        );
1510
1511        let le2 = list_iter.next().unwrap().unwrap();
1512        assert_eq!(
1513            le2.tlv().unwrap(),
1514            TLV {
1515                tag: TLVTag::Context(2),
1516                value: TLVValue::U8(6)
1517            }
1518        );
1519
1520        let le3 = list_iter.next().unwrap().unwrap();
1521        assert_eq!(
1522            le3.tlv().unwrap(),
1523            TLV {
1524                tag: TLVTag::Context(3),
1525                value: TLVValue::U8(1)
1526            }
1527        );
1528
1529        assert!(list_iter.next().is_none());
1530
1531        let struct2 = TLVStruct::<TLVElement>::new(struct1_iter.next().unwrap().unwrap()).unwrap();
1532        assert_eq!(
1533            struct2.element().tlv().unwrap(),
1534            TLV {
1535                tag: TLVTag::Context(1),
1536                value: TLVValue::Struct,
1537            }
1538        );
1539        assert_eq!(struct2.iter().count(), 0);
1540    }
1541
1542    #[test]
1543    fn test_matter_spec_examples() {
1544        let tlv = |slice| TLVElement::new(slice).tlv().unwrap();
1545
1546        // Boolean false
1547
1548        assert_eq!(
1549            tlv(&[0x08]),
1550            TLV {
1551                tag: TLVTag::Anonymous,
1552                value: TLVValue::False,
1553            }
1554        );
1555
1556        // Boolean true
1557
1558        assert_eq!(
1559            tlv(&[0x09]),
1560            TLV {
1561                tag: TLVTag::Anonymous,
1562                value: TLVValue::True,
1563            }
1564        );
1565
1566        // Signed Integer, 1-octet, value 42
1567
1568        assert_eq!(
1569            tlv(&[0x00, 0x2a]),
1570            TLV {
1571                tag: TLVTag::Anonymous,
1572                value: TLVValue::S8(42),
1573            }
1574        );
1575
1576        // Signed Integer, 1-octet, value -17
1577
1578        assert_eq!(
1579            tlv(&[0x00, 0xef]),
1580            TLV {
1581                tag: TLVTag::Anonymous,
1582                value: TLVValue::S8(-17),
1583            }
1584        );
1585
1586        // Unsigned Integer, 1-octet, value 42U
1587
1588        assert_eq!(
1589            tlv(&[0x04, 0x2a]),
1590            TLV {
1591                tag: TLVTag::Anonymous,
1592                value: TLVValue::U8(42),
1593            }
1594        );
1595
1596        // Signed Integer, 2-octet, value 42
1597
1598        assert_eq!(
1599            tlv(&[0x01, 0x2a, 0x00]),
1600            TLV {
1601                tag: TLVTag::Anonymous,
1602                value: TLVValue::S16(42),
1603            }
1604        );
1605
1606        // Signed Integer, 4-octet, value -170000
1607
1608        assert_eq!(
1609            tlv(&[0x02, 0xf0, 0x67, 0xfd, 0xff]),
1610            TLV {
1611                tag: TLVTag::Anonymous,
1612                value: TLVValue::S32(-170000),
1613            }
1614        );
1615
1616        // Signed Integer, 8-octet, value 40000000000
1617
1618        assert_eq!(
1619            tlv(&[0x03, 0x00, 0x90, 0x2f, 0x50, 0x09, 0x00, 0x00, 0x00]),
1620            TLV {
1621                tag: TLVTag::Anonymous,
1622                value: TLVValue::S64(40000000000),
1623            }
1624        );
1625
1626        // UTF-8 String, 1-octet length, "Hello!"
1627
1628        assert_eq!(
1629            tlv(&[0x0c, 0x06, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21]),
1630            TLV {
1631                tag: TLVTag::Anonymous,
1632                value: TLVValue::Utf8l("Hello!"),
1633            }
1634        );
1635
1636        // UTF-8 String, 1-octet length, "Tschüs"
1637
1638        assert_eq!(
1639            tlv(&[0x0c, 0x07, 0x54, 0x73, 0x63, 0x68, 0xc3, 0xbc, 0x73]),
1640            TLV {
1641                tag: TLVTag::Anonymous,
1642                value: TLVValue::Utf8l("Tschüs"),
1643            }
1644        );
1645
1646        // Octet String, 1-octet length, octets 00 01 02 03 04
1647
1648        assert_eq!(
1649            tlv(&[0x10, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04]),
1650            TLV {
1651                tag: TLVTag::Anonymous,
1652                value: TLVValue::Str8l(&[0x00, 0x01, 0x02, 0x03, 0x04]),
1653            }
1654        );
1655
1656        // Null
1657
1658        assert_eq!(
1659            tlv(&[0x14]),
1660            TLV {
1661                tag: TLVTag::Anonymous,
1662                value: TLVValue::Null,
1663            }
1664        );
1665
1666        // Single precision floating point 0.0
1667
1668        assert_eq!(
1669            tlv(&[0x0a, 0x00, 0x00, 0x00, 0x00]),
1670            TLV {
1671                tag: TLVTag::Anonymous,
1672                value: TLVValue::F32(0.0),
1673            }
1674        );
1675
1676        // Single precision floating point (1.0 / 3.0)
1677
1678        assert_eq!(
1679            tlv(&[0x0a, 0xab, 0xaa, 0xaa, 0x3e]),
1680            TLV {
1681                tag: TLVTag::Anonymous,
1682                value: TLVValue::F32(1.0 / 3.0),
1683            }
1684        );
1685
1686        // Single precision floating point 17.9
1687
1688        assert_eq!(
1689            tlv(&[0x0a, 0x33, 0x33, 0x8f, 0x41]),
1690            TLV {
1691                tag: TLVTag::Anonymous,
1692                value: TLVValue::F32(17.9),
1693            }
1694        );
1695
1696        // Single precision floating point infinity
1697
1698        assert_eq!(
1699            tlv(&[0x0a, 0x00, 0x00, 0x80, 0x7f]),
1700            TLV {
1701                tag: TLVTag::Anonymous,
1702                value: TLVValue::F32(f32::INFINITY),
1703            }
1704        );
1705
1706        // Single precision floating point negative infinity
1707
1708        assert_eq!(
1709            tlv(&[0x0a, 0x00, 0x00, 0x80, 0xff]),
1710            TLV {
1711                tag: TLVTag::Anonymous,
1712                value: TLVValue::F32(f32::NEG_INFINITY),
1713            }
1714        );
1715
1716        // Double precision floating point 0.0
1717
1718        assert_eq!(
1719            tlv(&[0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
1720            TLV {
1721                tag: TLVTag::Anonymous,
1722                value: TLVValue::F64(0.0),
1723            }
1724        );
1725
1726        // Double precision floating point (1.0 / 3.0)
1727
1728        assert_eq!(
1729            tlv(&[0x0b, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5, 0x3f]),
1730            TLV {
1731                tag: TLVTag::Anonymous,
1732                value: TLVValue::F64(1.0 / 3.0),
1733            }
1734        );
1735
1736        // Double precision floating point 17.9
1737
1738        assert_eq!(
1739            tlv(&[0x0b, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x31, 0x40]),
1740            TLV {
1741                tag: TLVTag::Anonymous,
1742                value: TLVValue::F64(17.9),
1743            }
1744        );
1745
1746        // Double precision floating point infinity (∞)
1747
1748        assert_eq!(
1749            tlv(&[0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f]),
1750            TLV {
1751                tag: TLVTag::Anonymous,
1752                value: TLVValue::F64(f64::INFINITY),
1753            }
1754        );
1755
1756        // Double precision floating point negative infinity
1757
1758        assert_eq!(
1759            tlv(&[0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff]),
1760            TLV {
1761                tag: TLVTag::Anonymous,
1762                value: TLVValue::F64(f64::NEG_INFINITY),
1763            }
1764        );
1765
1766        // Empty Structure, {}
1767
1768        assert_eq!(
1769            tlv(&[0x15, 0x18]),
1770            TLV {
1771                tag: TLVTag::Anonymous,
1772                value: TLVValue::Struct,
1773            }
1774        );
1775
1776        assert!(TLVElement::new(&[0x15, 0x18])
1777            .structure()
1778            .unwrap()
1779            .iter()
1780            .next()
1781            .is_none());
1782
1783        // Empty Array, []
1784
1785        assert_eq!(
1786            tlv(&[0x16, 0x18]),
1787            TLV {
1788                tag: TLVTag::Anonymous,
1789                value: TLVValue::Array,
1790            }
1791        );
1792
1793        assert!(TLVElement::new(&[0x16, 0x18])
1794            .array()
1795            .unwrap()
1796            .iter()
1797            .next()
1798            .is_none());
1799
1800        // Empty List, []
1801
1802        assert_eq!(
1803            tlv(&[0x17, 0x18]),
1804            TLV {
1805                tag: TLVTag::Anonymous,
1806                value: TLVValue::List,
1807            }
1808        );
1809
1810        assert!(TLVElement::new(&[0x17, 0x18])
1811            .list()
1812            .unwrap()
1813            .iter()
1814            .next()
1815            .is_none());
1816
1817        // Structure, two context specific tags, Signed Intger, 1 octet values, {0 = 42, 1 = -17}
1818
1819        let data = &[0x15, 0x20, 0x00, 0x2a, 0x20, 0x01, 0xef, 0x18];
1820
1821        assert_eq!(
1822            tlv(data),
1823            TLV {
1824                tag: TLVTag::Anonymous,
1825                value: TLVValue::Struct,
1826            }
1827        );
1828
1829        let mut iter = TLVElement::new(data).structure().unwrap().iter();
1830
1831        let s1 = iter.next().unwrap().unwrap();
1832        assert_eq!(s1.tag().unwrap(), TLVTag::Context(0));
1833        assert_eq!(s1.i32().unwrap(), 42);
1834
1835        let s2 = iter.next().unwrap().unwrap();
1836        assert_eq!(s2.tag().unwrap(), TLVTag::Context(1));
1837        assert_eq!(s2.i16().unwrap(), -17);
1838
1839        assert!(iter.next().is_none());
1840
1841        // Array, Signed Integer, 1-octet values, [0, 1, 2, 3, 4]
1842
1843        let data = &[
1844            0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x18,
1845        ];
1846
1847        assert_eq!(
1848            tlv(data),
1849            TLV {
1850                tag: TLVTag::Anonymous,
1851                value: TLVValue::Array,
1852            }
1853        );
1854
1855        let iter = TLVElement::new(data).array().unwrap().iter().enumerate();
1856
1857        for (index, elem) in iter {
1858            let elem = elem.unwrap();
1859
1860            assert_eq!(elem.tag().unwrap(), TLVTag::Anonymous);
1861            assert_eq!(elem.i8().unwrap(), index as i8);
1862        }
1863
1864        // List, mix of anonymous and context tags, Signed Integer, 1 octet values, [[1, 0 = 42, 2, 3, 0 = -17]]
1865
1866        let data = &[
1867            0x17, 0x00, 0x01, 0x20, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x03, 0x20, 0x00, 0xef, 0x18,
1868        ];
1869
1870        assert_eq!(
1871            tlv(data),
1872            TLV {
1873                tag: TLVTag::Anonymous,
1874                value: TLVValue::List,
1875            }
1876        );
1877
1878        let expected = &[
1879            TLV {
1880                tag: TLVTag::Anonymous,
1881                value: TLVValue::S8(1),
1882            },
1883            TLV {
1884                tag: TLVTag::Context(0),
1885                value: TLVValue::S8(42),
1886            },
1887            TLV {
1888                tag: TLVTag::Anonymous,
1889                value: TLVValue::S8(2),
1890            },
1891            TLV {
1892                tag: TLVTag::Anonymous,
1893                value: TLVValue::S8(3),
1894            },
1895            TLV {
1896                tag: TLVTag::Context(0),
1897                value: TLVValue::S8(-17),
1898            },
1899        ];
1900
1901        let mut iter = TLVElement::new(data).list().unwrap().iter();
1902
1903        for elem in expected {
1904            assert_eq!(iter.next().unwrap().unwrap().tlv().unwrap(), *elem);
1905        }
1906
1907        assert!(iter.next().is_none());
1908
1909        // Array, mix of element types, [42, -170000, {}, 17.9, "Hello!"]
1910
1911        let data = &[
1912            0x16, 0x00, 0x2a, 0x02, 0xf0, 0x67, 0xfd, 0xff, 0x15, 0x18, 0x0a, 0x33, 0x33, 0x8f,
1913            0x41, 0x0c, 0x06, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0x18,
1914        ];
1915
1916        assert_eq!(
1917            tlv(data),
1918            TLV {
1919                tag: TLVTag::Anonymous,
1920                value: TLVValue::Array,
1921            }
1922        );
1923
1924        let mut iter = TLVElement::new(data).array().unwrap().iter();
1925
1926        assert_eq!(
1927            iter.next().unwrap().unwrap().tlv().unwrap(),
1928            TLV {
1929                tag: TLVTag::Anonymous,
1930                value: TLVValue::S8(42),
1931            }
1932        );
1933
1934        assert_eq!(
1935            iter.next().unwrap().unwrap().tlv().unwrap(),
1936            TLV {
1937                tag: TLVTag::Anonymous,
1938                value: TLVValue::S32(-170000),
1939            }
1940        );
1941
1942        assert_eq!(
1943            iter.next().unwrap().unwrap().tlv().unwrap(),
1944            TLV {
1945                tag: TLVTag::Anonymous,
1946                value: TLVValue::Struct,
1947            }
1948        );
1949
1950        assert_eq!(
1951            iter.next().unwrap().unwrap().tlv().unwrap(),
1952            TLV {
1953                tag: TLVTag::Anonymous,
1954                value: TLVValue::F32(17.9),
1955            }
1956        );
1957
1958        assert_eq!(
1959            iter.next().unwrap().unwrap().tlv().unwrap(),
1960            TLV {
1961                tag: TLVTag::Anonymous,
1962                value: TLVValue::Utf8l("Hello!"),
1963            }
1964        );
1965
1966        // Anonymous tag, Unsigned Integer, 1-octet value, 42U
1967
1968        assert_eq!(
1969            tlv(&[0x04, 0x2a]),
1970            TLV {
1971                tag: TLVTag::Anonymous,
1972                value: TLVValue::U8(42),
1973            }
1974        );
1975
1976        // Context tag 1, Unsigned Integer, 1-octet value, 1 = 42U
1977
1978        assert_eq!(
1979            tlv(&[0x24, 0x01, 0x2a]),
1980            TLV {
1981                tag: TLVTag::Context(1),
1982                value: TLVValue::U8(42),
1983            }
1984        );
1985
1986        // Common profile tag 1, Unsigned Integer, 1-octet value, Matter::1 = 42U
1987
1988        assert_eq!(
1989            tlv(&[0x44, 0x01, 0x00, 0x2a]),
1990            TLV {
1991                tag: TLVTag::CommonPrf16(1),
1992                value: TLVValue::U8(42),
1993            }
1994        );
1995
1996        // Common profile tag 100000, Unsigned Integer, 1-octet value, Matter::100000 = 42U
1997
1998        assert_eq!(
1999            tlv(&[0x64, 0xa0, 0x86, 0x01, 0x00, 0x2a]),
2000            TLV {
2001                tag: TLVTag::CommonPrf32(100000),
2002                value: TLVValue::U8(42),
2003            }
2004        );
2005
2006        // Fully qualified tag, Vendor ID 0xFFF1/65521, pro­file number 0xDEED/57069,
2007        // 2-octet tag 1, Unsigned Integer, 1-octet value 42, 65521::57069:1 = 42U
2008
2009        assert_eq!(
2010            tlv(&[0xc4, 0xf1, 0xff, 0xed, 0xde, 0x01, 0x00, 0x2a]),
2011            TLV {
2012                tag: TLVTag::FullQual48 {
2013                    vendor_id: 65521,
2014                    profile: 57069,
2015                    tag: 1,
2016                },
2017                value: TLVValue::U8(42),
2018            }
2019        );
2020
2021        // Fully qualified tag, Vendor ID 0xFFF1/65521, pro­file number 0xDEED/57069,
2022        // 4-octet tag 0xAA55FEED/2857762541, Unsigned Integer, 1-octet value 42, 65521::57069:2857762541 = 42U
2023
2024        assert_eq!(
2025            tlv(&[0xe4, 0xf1, 0xff, 0xed, 0xde, 0xed, 0xfe, 0x55, 0xaa, 0x2a]),
2026            TLV {
2027                tag: TLVTag::FullQual64 {
2028                    vendor_id: 65521,
2029                    profile: 57069,
2030                    tag: 2857762541,
2031                },
2032                value: TLVValue::U8(42),
2033            }
2034        );
2035
2036        // Structure with the fully qualified tag, Vendor ID 0xFFF1/65521, profile number 0xDEED/57069,
2037        // 2-octet tag 1. The structure contains a single ele­ment labeled using a fully qualified tag under
2038        // the same profile, with 2-octet tag 0xAA55/43605. 65521::57069:1 = {65521::57069:43605 = 42U}
2039
2040        let data = &[
2041            0xd5, 0xf1, 0xff, 0xed, 0xde, 0x01, 0x00, 0xc4, 0xf1, 0xff, 0xed, 0xde, 0x55, 0xaa,
2042            0x2a, 0x18,
2043        ];
2044
2045        assert_eq!(
2046            tlv(data),
2047            TLV {
2048                tag: TLVTag::FullQual48 {
2049                    vendor_id: 65521,
2050                    profile: 57069,
2051                    tag: 1,
2052                },
2053                value: TLVValue::Struct,
2054            }
2055        );
2056
2057        let mut iter = TLVElement::new(data).structure().unwrap().iter();
2058
2059        let u1 = iter.next().unwrap().unwrap();
2060
2061        assert_eq!(
2062            u1.tag().unwrap(),
2063            TLVTag::FullQual48 {
2064                vendor_id: 65521,
2065                profile: 57069,
2066                tag: 43605,
2067            }
2068        );
2069
2070        assert_eq!(u1.u8().unwrap(), 42);
2071
2072        assert!(iter.next().is_none());
2073    }
2074}