use core::marker::PhantomData;
use crate::error::Error;
use crate::im::encoding::{AttrId, ClusterId, EndptId};
use crate::im::{
AttrPath, AttrPathTag, DataVersionFilter, EventFilter, EventPath, NodeId, ReadReqTag,
IM_REVISION,
};
use crate::tlv::{TLVBuilder, TLVBuilderParent, TLVTag, TLVWrite, ToTLV};
pub struct ReadReqBuilder<P, const F: usize = 0> {
p: P,
}
impl<P> ReadReqBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn new(mut p: P, tag: &TLVTag) -> Result<Self, Error> {
p.writer().start_struct(tag)?;
Ok(Self { p })
}
}
impl<P> TLVBuilder<P> for ReadReqBuilder<P, 0>
where
P: TLVBuilderParent,
{
fn new(parent: P, tag: &TLVTag) -> Result<Self, Error> {
Self::new(parent, tag)
}
fn unchecked_into_parent(self) -> P {
self.p
}
}
impl<P> ReadReqBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn attr_requests(self) -> Result<AttrPathArrayBuilder<ReadReqBuilder<P, 1>>, Error> {
AttrPathArrayBuilder::new(
ReadReqBuilder { p: self.p },
&TLVTag::Context(ReadReqTag::AttrRequests as u8),
)
}
pub fn attr_requests_from(mut self, paths: &[AttrPath]) -> Result<ReadReqBuilder<P, 1>, Error> {
let w = self.p.writer();
w.start_array(&TLVTag::Context(ReadReqTag::AttrRequests as u8))?;
for p in paths {
p.to_tlv(&TLVTag::Anonymous, &mut *w)?;
}
w.end_container()?;
Ok(ReadReqBuilder { p: self.p })
}
}
impl<P> ReadReqBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn event_requests_from(self, paths: &[EventPath]) -> Result<ReadReqBuilder<P, 2>, Error> {
ReadReqBuilder::<P, 1> { p: self.p }.event_requests_from(paths)
}
}
impl<P> ReadReqBuilder<P, 1>
where
P: TLVBuilderParent,
{
pub fn event_requests_from(
mut self,
paths: &[EventPath],
) -> Result<ReadReqBuilder<P, 2>, Error> {
let w = self.p.writer();
w.start_array(&TLVTag::Context(ReadReqTag::EventRequests as u8))?;
for p in paths {
p.to_tlv(&TLVTag::Anonymous, &mut *w)?;
}
w.end_container()?;
Ok(ReadReqBuilder { p: self.p })
}
}
impl<P> ReadReqBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn event_filters_from(
self,
filters: &[EventFilter],
) -> Result<ReadReqBuilder<P, 3>, Error> {
ReadReqBuilder::<P, 2> { p: self.p }.event_filters_from(filters)
}
}
impl<P> ReadReqBuilder<P, 1>
where
P: TLVBuilderParent,
{
pub fn event_filters_from(
self,
filters: &[EventFilter],
) -> Result<ReadReqBuilder<P, 3>, Error> {
ReadReqBuilder::<P, 2> { p: self.p }.event_filters_from(filters)
}
}
impl<P> ReadReqBuilder<P, 2>
where
P: TLVBuilderParent,
{
pub fn event_filters_from(
mut self,
filters: &[EventFilter],
) -> Result<ReadReqBuilder<P, 3>, Error> {
let w = self.p.writer();
w.start_array(&TLVTag::Context(ReadReqTag::EventFilters as u8))?;
for ef in filters {
ef.to_tlv(&TLVTag::Anonymous, &mut *w)?;
}
w.end_container()?;
Ok(ReadReqBuilder { p: self.p })
}
}
impl<P> ReadReqBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn fabric_filtered(self, value: bool) -> Result<ReadReqBuilder<P, 4>, Error> {
ReadReqBuilder::<P, 3> { p: self.p }.fabric_filtered(value)
}
}
impl<P> ReadReqBuilder<P, 1>
where
P: TLVBuilderParent,
{
pub fn fabric_filtered(self, value: bool) -> Result<ReadReqBuilder<P, 4>, Error> {
ReadReqBuilder::<P, 3> { p: self.p }.fabric_filtered(value)
}
}
impl<P> ReadReqBuilder<P, 2>
where
P: TLVBuilderParent,
{
pub fn fabric_filtered(self, value: bool) -> Result<ReadReqBuilder<P, 4>, Error> {
ReadReqBuilder::<P, 3> { p: self.p }.fabric_filtered(value)
}
}
impl<P> ReadReqBuilder<P, 3>
where
P: TLVBuilderParent,
{
pub fn fabric_filtered(mut self, value: bool) -> Result<ReadReqBuilder<P, 4>, Error> {
self.p
.writer()
.bool(&TLVTag::Context(ReadReqTag::FabricFiltered as u8), value)?;
Ok(ReadReqBuilder { p: self.p })
}
}
impl<P> ReadReqBuilder<P, 4>
where
P: TLVBuilderParent,
{
pub fn dataver_filters_from(
mut self,
filters: &[DataVersionFilter],
) -> Result<ReadReqBuilder<P, 5>, Error> {
let w = self.p.writer();
w.start_array(&TLVTag::Context(ReadReqTag::DataVersionFilters as u8))?;
for f in filters {
f.to_tlv(&TLVTag::Anonymous, &mut *w)?;
}
w.end_container()?;
Ok(ReadReqBuilder { p: self.p })
}
}
impl<P> ReadReqBuilder<P, 4>
where
P: TLVBuilderParent,
{
pub fn end(self) -> Result<P, Error> {
ReadReqBuilder::<P, 5> { p: self.p }.end()
}
}
impl<P> ReadReqBuilder<P, 4>
where
P: TLVBuilderParent,
{
pub fn interaction_model_revision(self, value: u8) -> Result<ReadReqBuilder<P, 6>, Error> {
ReadReqBuilder::<P, 5> { p: self.p }.interaction_model_revision(value)
}
}
impl<P> ReadReqBuilder<P, 5>
where
P: TLVBuilderParent,
{
pub fn interaction_model_revision(mut self, value: u8) -> Result<ReadReqBuilder<P, 6>, Error> {
self.p.writer().u8(
&TLVTag::Context(crate::im::encoding::IM_REVISION_TAG),
value,
)?;
Ok(ReadReqBuilder { p: self.p })
}
pub fn end(self) -> Result<P, Error> {
self.interaction_model_revision(IM_REVISION)?.end()
}
}
impl<P> ReadReqBuilder<P, 6>
where
P: TLVBuilderParent,
{
pub fn end(mut self) -> Result<P, Error> {
self.p.writer().end_container()?;
Ok(self.p)
}
}
impl<P, const F: usize> TLVBuilderParent for ReadReqBuilder<P, F>
where
P: TLVBuilderParent,
{
type Write = P::Write;
fn writer(&mut self) -> &mut Self::Write {
self.p.writer()
}
}
impl<P, const F: usize> core::fmt::Debug for ReadReqBuilder<P, F>
where
P: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}::ReadRequestMessage<{}>", self.p, F)
}
}
#[cfg(feature = "defmt")]
impl<P, const F: usize> defmt::Format for ReadReqBuilder<P, F>
where
P: defmt::Format,
{
fn format(&self, fmt: defmt::Formatter<'_>) {
defmt::write!(fmt, "{:?}::ReadRequestMessage<{}>", self.p, F);
}
}
pub struct AttrPathArrayBuilder<P> {
p: P,
}
impl<P> AttrPathArrayBuilder<P>
where
P: TLVBuilderParent,
{
pub fn new(mut p: P, tag: &TLVTag) -> Result<Self, Error> {
p.writer().start_array(tag)?;
Ok(Self { p })
}
pub fn push(self) -> Result<AttrPathBuilder<Self, 0>, Error> {
AttrPathBuilder::new(self, &TLVTag::Anonymous)
}
pub fn end(mut self) -> Result<P, Error> {
self.p.writer().end_container()?;
Ok(self.p)
}
}
impl<P> TLVBuilder<P> for AttrPathArrayBuilder<P>
where
P: TLVBuilderParent,
{
fn new(parent: P, tag: &TLVTag) -> Result<Self, Error> {
Self::new(parent, tag)
}
fn unchecked_into_parent(self) -> P {
self.p
}
}
impl<P> TLVBuilderParent for AttrPathArrayBuilder<P>
where
P: TLVBuilderParent,
{
type Write = P::Write;
fn writer(&mut self) -> &mut Self::Write {
self.p.writer()
}
}
impl<P> core::fmt::Debug for AttrPathArrayBuilder<P>
where
P: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}[]", self.p)
}
}
#[cfg(feature = "defmt")]
impl<P> defmt::Format for AttrPathArrayBuilder<P>
where
P: defmt::Format,
{
fn format(&self, fmt: defmt::Formatter<'_>) {
defmt::write!(fmt, "{:?}[]", self.p);
}
}
pub struct AttrPathBuilder<P, const F: usize = 0> {
p: P,
_f: PhantomData<[(); F]>,
}
impl<P> AttrPathBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn new(mut p: P, tag: &TLVTag) -> Result<Self, Error> {
p.writer().start_list(tag)?;
Ok(Self { p, _f: PhantomData })
}
}
impl<P> TLVBuilder<P> for AttrPathBuilder<P, 0>
where
P: TLVBuilderParent,
{
fn new(parent: P, tag: &TLVTag) -> Result<Self, Error> {
Self::new(parent, tag)
}
fn unchecked_into_parent(self) -> P {
self.p
}
}
impl<P> AttrPathBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn node(mut self, value: NodeId) -> Result<AttrPathBuilder<P, 1>, Error> {
self.p
.writer()
.u64(&TLVTag::Context(AttrPathTag::Node as u8), value)?;
Ok(AttrPathBuilder {
p: self.p,
_f: PhantomData,
})
}
}
impl<P> AttrPathBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn endpoint(self, value: EndptId) -> Result<AttrPathBuilder<P, 2>, Error> {
AttrPathBuilder::<P, 1> {
p: self.p,
_f: PhantomData,
}
.endpoint(value)
}
}
impl<P> AttrPathBuilder<P, 1>
where
P: TLVBuilderParent,
{
pub fn endpoint(mut self, value: EndptId) -> Result<AttrPathBuilder<P, 2>, Error> {
self.p
.writer()
.u16(&TLVTag::Context(AttrPathTag::Endpoint as u8), value)?;
Ok(AttrPathBuilder {
p: self.p,
_f: PhantomData,
})
}
}
impl<P> AttrPathBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn cluster(self, value: ClusterId) -> Result<AttrPathBuilder<P, 3>, Error> {
AttrPathBuilder::<P, 2> {
p: self.p,
_f: PhantomData,
}
.cluster(value)
}
}
impl<P> AttrPathBuilder<P, 1>
where
P: TLVBuilderParent,
{
pub fn cluster(self, value: ClusterId) -> Result<AttrPathBuilder<P, 3>, Error> {
AttrPathBuilder::<P, 2> {
p: self.p,
_f: PhantomData,
}
.cluster(value)
}
}
impl<P> AttrPathBuilder<P, 2>
where
P: TLVBuilderParent,
{
pub fn cluster(mut self, value: ClusterId) -> Result<AttrPathBuilder<P, 3>, Error> {
self.p
.writer()
.u32(&TLVTag::Context(AttrPathTag::Cluster as u8), value)?;
Ok(AttrPathBuilder {
p: self.p,
_f: PhantomData,
})
}
}
impl<P> AttrPathBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn attr(self, value: AttrId) -> Result<AttrPathBuilder<P, 4>, Error> {
AttrPathBuilder::<P, 3> {
p: self.p,
_f: PhantomData,
}
.attr(value)
}
}
impl<P> AttrPathBuilder<P, 1>
where
P: TLVBuilderParent,
{
pub fn attr(self, value: AttrId) -> Result<AttrPathBuilder<P, 4>, Error> {
AttrPathBuilder::<P, 3> {
p: self.p,
_f: PhantomData,
}
.attr(value)
}
}
impl<P> AttrPathBuilder<P, 2>
where
P: TLVBuilderParent,
{
pub fn attr(self, value: AttrId) -> Result<AttrPathBuilder<P, 4>, Error> {
AttrPathBuilder::<P, 3> {
p: self.p,
_f: PhantomData,
}
.attr(value)
}
}
impl<P> AttrPathBuilder<P, 3>
where
P: TLVBuilderParent,
{
pub fn attr(mut self, value: AttrId) -> Result<AttrPathBuilder<P, 4>, Error> {
self.p
.writer()
.u32(&TLVTag::Context(AttrPathTag::Attribute as u8), value)?;
Ok(AttrPathBuilder {
p: self.p,
_f: PhantomData,
})
}
}
impl<P> AttrPathBuilder<P, 4>
where
P: TLVBuilderParent,
{
pub fn list_index(mut self, value: Option<u16>) -> Result<AttrPathBuilder<P, 5>, Error> {
let n: crate::tlv::Nullable<u16> = match value {
Some(v) => crate::tlv::Nullable::some(v),
None => crate::tlv::Nullable::none(),
};
n.to_tlv(
&TLVTag::Context(AttrPathTag::ListIndex as u8),
self.p.writer(),
)?;
Ok(AttrPathBuilder {
p: self.p,
_f: PhantomData,
})
}
}
impl<P> AttrPathBuilder<P, 0>
where
P: TLVBuilderParent,
{
pub fn end(self) -> Result<P, Error> {
AttrPathBuilder::<P, 5> {
p: self.p,
_f: PhantomData,
}
.end()
}
}
impl<P> AttrPathBuilder<P, 1>
where
P: TLVBuilderParent,
{
pub fn end(self) -> Result<P, Error> {
AttrPathBuilder::<P, 5> {
p: self.p,
_f: PhantomData,
}
.end()
}
}
impl<P> AttrPathBuilder<P, 2>
where
P: TLVBuilderParent,
{
pub fn end(self) -> Result<P, Error> {
AttrPathBuilder::<P, 5> {
p: self.p,
_f: PhantomData,
}
.end()
}
}
impl<P> AttrPathBuilder<P, 3>
where
P: TLVBuilderParent,
{
pub fn end(self) -> Result<P, Error> {
AttrPathBuilder::<P, 5> {
p: self.p,
_f: PhantomData,
}
.end()
}
}
impl<P> AttrPathBuilder<P, 4>
where
P: TLVBuilderParent,
{
pub fn end(self) -> Result<P, Error> {
AttrPathBuilder::<P, 5> {
p: self.p,
_f: PhantomData,
}
.end()
}
}
impl<P> AttrPathBuilder<P, 5>
where
P: TLVBuilderParent,
{
pub fn end(mut self) -> Result<P, Error> {
self.p.writer().end_container()?;
Ok(self.p)
}
}
impl<P, const F: usize> TLVBuilderParent for AttrPathBuilder<P, F>
where
P: TLVBuilderParent,
{
type Write = P::Write;
fn writer(&mut self) -> &mut Self::Write {
self.p.writer()
}
}
impl<P, const F: usize> core::fmt::Debug for AttrPathBuilder<P, F>
where
P: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}::AttrPath<{}>", self.p, F)
}
}
#[cfg(feature = "defmt")]
impl<P, const F: usize> defmt::Format for AttrPathBuilder<P, F>
where
P: defmt::Format,
{
fn format(&self, fmt: defmt::Formatter<'_>) {
defmt::write!(fmt, "{:?}::AttrPath<{}>", self.p, F);
}
}