Skip to main content

TlvReader

Struct TlvReader 

Source
pub struct TlvReader<'a> { /* private fields */ }
Expand description

A streaming TLV decoder over a borrowed byte slice.

Implementations§

Source§

impl<'a> TlvReader<'a>

Source

pub fn new(bytes: &'a [u8]) -> Self

Construct a reader that walks bytes from the start, using the DEFAULT_ELEMENT_BUDGET for tree-builder decodes.

Source

pub fn with_element_budget(bytes: &'a [u8], budget: usize) -> Self

Construct a reader with a custom total-element budget for tree-builder decoding (see DEFAULT_ELEMENT_BUDGET).

A Self::read_value call that would materialise more than budget Value elements fails with Error::ElementBudgetExceeded. The budget only affects the tree-builder path; the streaming Self::next API is unaffected because it allocates nothing per element.

Source

pub fn is_empty(&self) -> bool

Whether there is no more input to consume.

Source

pub fn next(&mut self) -> Result<Option<Element>>

Advance one TLV element. Returns Ok(None) at end of input.

§Errors

Returns Err if the input is malformed:

§Note on naming

This method is deliberately named next to match the streaming-reader idiom established by e.g. serde’s Deserializer. It returns Result<Option<T>> rather than Option<Result<T>> so that callers use ? naturally. Implementing std::iter::Iterator is deferred to a later phase when a fallible-iterator adapter is available.

Source

pub fn skip_container(&mut self) -> Result<()>

Skip the remaining body of the container whose ContainerStart was just returned by Self::next, consuming through its matching ContainerEnd.

Call this immediately after next() yields a ContainerStart you want to discard — for example an unknown field carried by a struct from a newer Matter revision. On return the reader is positioned at the first element after the skipped container. Scalars inside the container are walked but not materialised, so cost is bounded by the input size and nesting by MAX_DEPTH (both enforced by next()).

§Errors
  • Error::UnclosedContainer — end of input before the container’s closing marker.
  • Any error returned by Self::next (malformed body, over-deep nesting, or element-budget exhaustion).
§Examples
use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter};
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)?;
w.start_structure(Tag::Context(9))?; // an unknown nested field
w.end_container()?;
w.put_uint(Tag::Context(1), 42)?;
w.end_container()?;

let mut r = TlvReader::new(&buf);
r.next()?; // open the outer struct
// next() returns the nested ctx9 ContainerStart we want to discard:
assert!(matches!(
    r.next()?,
    Some(Element::ContainerStart { kind: ContainerKind::Structure, .. })
));
r.skip_container()?; // drain the nested struct
// the field after the unknown container is still readable:
assert!(matches!(r.next()?, Some(Element::Scalar { tag: Tag::Context(1), .. })));
Source

pub fn read_value(&mut self) -> Result<(Tag, Value)>

Materialise one full TLV element as a (Tag, Value). Scalars are returned directly; containers are read recursively up to MAX_DEPTH levels (enforced by Self::next’s depth counter).

§Errors

Auto Trait Implementations§

§

impl<'a> Freeze for TlvReader<'a>

§

impl<'a> RefUnwindSafe for TlvReader<'a>

§

impl<'a> Send for TlvReader<'a>

§

impl<'a> Sync for TlvReader<'a>

§

impl<'a> Unpin for TlvReader<'a>

§

impl<'a> UnsafeUnpin for TlvReader<'a>

§

impl<'a> UnwindSafe for TlvReader<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.