pub trait ImClient<'a>: Sized + Into<Exchange<'a>> {
// Provided methods
async fn read_with<B>(self, build: B) -> Result<ReadRespChunk<'a>, Error>
where B: FnMut(ReadReqBuilder<ReadSender<'a>>) -> Result<ReadSender<'a>, Error> { ... }
async fn read_sender(self) -> Result<ReadSender<'a>, Error> { ... }
async fn write_with<B>(
self,
timed_timeout_ms: Option<u16>,
build: B,
) -> Result<WriteRespHandle<'a>, Error>
where B: FnMut(WriteReqBuilder<WriteSender<'a>>) -> Result<WriteSender<'a>, Error> { ... }
async fn write_sender(
self,
timed_timeout_ms: Option<u16>,
) -> Result<WriteSender<'a>, Error> { ... }
async fn invoke_with<B>(
self,
timed_timeout_ms: Option<u16>,
build: B,
) -> Result<InvokeRespChunk<'a>, Error>
where B: FnMut(InvReqBuilder<InvokeSender<'a>>) -> Result<InvokeSender<'a>, Error> { ... }
async fn invoke_sender(
self,
timed_timeout_ms: Option<u16>,
) -> Result<InvokeSender<'a>, Error> { ... }
async fn subscribe_with<B>(
self,
build: B,
) -> Result<SubscribePrimingChunk<'a>, Error>
where B: FnMut(SubscribeReqBuilder<SubscribeSender<'a>>) -> Result<SubscribeSender<'a>, Error> { ... }
async fn subscribe_sender(self) -> Result<SubscribeSender<'a>, Error> { ... }
}Expand description
IM Client trait — extension over an Exchange that adds the
Matter Interaction Model client operations.
Implemented for Exchange<'a>; user code just uses this trait
to get method-syntax access on any exchange handle. Two flavours
of method live on this trait:
*_sender— hands the caller a typed*Senderthey drive manually. Maximum control, full visibility into the retransmit loop and chunked response iteration.*_with/*_with_async— takes a build closure that writes the request straight into the TX buffer; the retransmit loop is handled internally and the first response chunk is handed back for the caller to iterate viacomplete().
On top of these, the codegen-emitted per-cluster
<ClusterName>Client<'a> traits add high-level single-shot
methods (<cluster>_<command> / <cluster>_<attr>_read /
<cluster>_<attr>_write) that bake in the cluster/attr/cmd IDs
and the chunk-drain / status-to-error conversion for the common
case.
The trait sits over Self: Into<Exchange<'a>> so any type that
converts to an exchange can opt in via a one-line blanket impl;
Exchange<'a> itself implements Into<Exchange<'a>> for free via
the standard-library identity impl.
§Lifecycle
Every method consumes the exchange (self by value) — one
exchange is one IM transaction, end of story. After the method
returns, the exchange is closed and the slot is released; callers
wanting to issue another transaction must initiate a fresh
exchange.
Provided Methods§
Sourceasync fn read_with<B>(self, build: B) -> Result<ReadRespChunk<'a>, Error>
async fn read_with<B>(self, build: B) -> Result<ReadRespChunk<'a>, Error>
Perform an IM read transaction.
§Arguments
buildclosure that writes theReadRequestMessageTLV body NOTE: The closure isFnMutbecause the MRP layer may retransmit the request multiple times; it MUST produce the same TLV output on every call.
§Returns
Ok(ReadRespChunk)for the first response chunk; multi-chunkReportDatastreams iterate viaReadRespChunk::complete()Errif the transaction fails at any point (request build, I/O, response parsing, etc.)
Sourceasync fn read_sender(self) -> Result<ReadSender<'a>, Error>
async fn read_sender(self) -> Result<ReadSender<'a>, Error>
Perform an IM read transaction without using a closure.
§Returns
Ok(ReadSender)ready for the caller to drive manually viaReadSender::tx()The first call toReadSender::txyields the initial builder. Seeinvoke_senderfor the full pattern.Errif the transaction fails at any point (I/O, etc.)
Sourceasync fn write_with<B>(
self,
timed_timeout_ms: Option<u16>,
build: B,
) -> Result<WriteRespHandle<'a>, Error>
async fn write_with<B>( self, timed_timeout_ms: Option<u16>, build: B, ) -> Result<WriteRespHandle<'a>, Error>
Perform an IM write transaction.
§Arguments
buildclosure that writes theWriteRequestMessageTLV body. NOTE: the closure isFnMutbecause the MRP layer may retransmit the request multiple times; it MUST produce the same TLV output on every call.
§Returns
Ok(WriteRespHandle)once the request is ACK-ed and the response is parsed; callWriteRespHandle::response()to inspect the parsedWriteResp.Errif the transaction fails at any point (request build, I/O, response parsing, etc.)
Sourceasync fn write_sender(
self,
timed_timeout_ms: Option<u16>,
) -> Result<WriteSender<'a>, Error>
async fn write_sender( self, timed_timeout_ms: Option<u16>, ) -> Result<WriteSender<'a>, Error>
Perform an IM write transaction without using a closure.
§Arguments
timed_timeout_msifSome, perform the initial handshake via aTimedRequestwith the given timeout (in milliseconds)
§Returns
Ok(WriteSender)ready for the caller to drive manually viaWriteSender::tx()The first call toWriteSender::txyields the initial builder. Seeinvoke_senderfor the full pattern.Errif the transaction fails at any point (I/O, etc.)
Sourceasync fn invoke_with<B>(
self,
timed_timeout_ms: Option<u16>,
build: B,
) -> Result<InvokeRespChunk<'a>, Error>
async fn invoke_with<B>( self, timed_timeout_ms: Option<u16>, build: B, ) -> Result<InvokeRespChunk<'a>, Error>
Perform an IM invoke transaction.
§Arguments
timed_timeout_msifSome, perform the initial handshake via aTimedRequestwith the given timeout (in milliseconds)buildclosure that writes theInvokeRequestMessageTLV body NOTE: The closure isFnMutbecause the MRP layer may retransmit the request multiple times; it MUST produce the same TLV output on every call.
§Returns
Ok(InvokeRespChunk)once the request is ACK-ed and the first response chunk is parsed; multi-chunkInvokeResponsestreams iterate viaInvokeRespChunk::complete().Errif the transaction fails at any point (request build, I/O, response parsing, etc.)
Sourceasync fn invoke_sender(
self,
timed_timeout_ms: Option<u16>,
) -> Result<InvokeSender<'a>, Error>
async fn invoke_sender( self, timed_timeout_ms: Option<u16>, ) -> Result<InvokeSender<'a>, Error>
Perform an IM invoke transaction without using a closure.
§Arguments
timed_timeout_msifSome, perform the initial handshake via aTimedRequestwith the given timeout (in milliseconds)
§Returns
Ok(InvokeSender)ready for the caller to drive manually viaInvokeSender::tx(). The first call toInvokeSender::txyields the initial builder.Errif the transaction fails at any point (I/O, etc.)
§Lifecycle
let mut sender = exchange.invoke_sender(None).await?;loop { match sender.tx().await? { TxOutcome::BuildRequest(b) => sender = build(b)?, TxOutcome::GotResponse(c) => break c } }loop { let resp = chunk.response()?; …; match chunk.complete().await? { … } }
Sourceasync fn subscribe_with<B>(
self,
build: B,
) -> Result<SubscribePrimingChunk<'a>, Error>
async fn subscribe_with<B>( self, build: B, ) -> Result<SubscribePrimingChunk<'a>, Error>
Perform the establishment phase of an IM subscribe transaction.
On the wire the establishment is a sequence of priming
ReportData chunks (each ACK-ed by the client with
StatusResponse(Success)) followed by a single
SubscribeResponse carrying subscription_id and the chosen
max_int. This method drives the request side and hands the
caller back the first priming chunk; the caller iterates
further priming chunks (and gets the terminal
SubscribeEstablished) via SubscribePrimingChunk::complete.
§Arguments
build— closure that writes theSubscribeRequestMessageTLV body via the streamingSubscribeReqBuilder. NOTE:FnMutbecause the MRP layer may retransmit the request; it MUST produce the same TLV output on every call.
§Returns
Ok(SubscribePrimingChunk)for the first priming chunk; walk the chunk loop viaSubscribePrimingChunk::complete.Erron any failure (request build, I/O, response parsing, peer-side validationStatusResponse(non-Success), …)
§Scope: establishment only
The active subscription phase — server-initiated
ReportData messages arriving on new exchanges throughout
the lifetime of the subscription — is not covered by
this method. That requires a listening loop on the
fabric/peer-node pair and is a separate piece of
infrastructure to layer on top. Once the
SubscribeEstablished is returned, the
fabric+peer+subscription-id triple identifies the active
subscription for any such future incoming reports.
Sourceasync fn subscribe_sender(self) -> Result<SubscribeSender<'a>, Error>
async fn subscribe_sender(self) -> Result<SubscribeSender<'a>, Error>
Perform the establishment phase of an IM subscribe transaction without using a closure.
§Returns
Ok(SubscribeSender)ready to be driven manually viaSubscribeSender::tx. The first call yields the initialSubscribeReqBuilder.Errif the underlying exchange handoff fails.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
impl<'a> ImClient<'a> for Exchange<'a>
Blanket impl so any Exchange<'a> is an ImClient<'a> when
the trait is used. The default-method bodies do all the work;
this impl just opts the type in.