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