pub trait ConnExt {
Show 17 methods
// Required methods
fn set_followup(&mut self, conn: Conn) -> &mut Self;
fn followup(&self) -> Option<&Conn>;
fn take_followup(&mut self) -> Option<Conn>;
fn error(&self) -> Option<&Error>;
fn set_error(&mut self, error: Error) -> &mut Self;
fn take_error(&mut self) -> Option<Error>;
fn halt(&mut self) -> &mut Self;
fn set_halted(&mut self, halted: bool) -> &mut Self;
fn is_halted(&self) -> bool;
fn set_response_body(&mut self, body: impl Into<Body>) -> &mut Self;
fn with_response_body(self, body: impl Into<Body>) -> Self
where Self: Sized;
fn set_status(&mut self, status: Status) -> &mut Self;
fn with_status(self, status: Status) -> Self
where Self: Sized;
fn response_headers_mut(&mut self) -> &mut Headers;
fn set_response_headers(&mut self, response_headers: Headers) -> &mut Self;
fn response_trailers_mut(&mut self) -> Option<&mut Headers>;
fn set_response_trailers(&mut self, response_trailers: Headers) -> &mut Self;
}Expand description
The extension trait handler authors use to drive the ClientHandler lifecycle.
These methods govern flow within the handler chain — queue a follow-up request for the
IntoFuture for &mut Conn loop to re-execute, or stash /
inspect / recover the transport-level error that runs through after_response. They
are meaningful only from inside a ClientHandler implementation: external user code
holding a Conn has no reason to call them. A queued follow-up is picked up only by
the handler-chain loop; an externally-installed error just turns into an Err on the
next .await.
Bring the methods into scope with use trillium_client::ConnExt;. The split
from Conn’s inherent methods is intentional — these affordances live on a trait
so handler authors opt into them explicitly and user code holding a Conn directly
doesn’t see them in IDE completion.
Required Methods§
Sourcefn set_followup(&mut self, conn: Conn) -> &mut Self
fn set_followup(&mut self, conn: Conn) -> &mut Self
Queue a follow-up Conn to be executed after the current cycle’s
after_response chain has fully unwound.
The follow-up is picked up by the IntoFuture for &mut Conn
loop, which drains and recycles the current conn’s response body, then runs a fresh
(run → network → after_response) cycle on the follow-up. After the loop finishes,
the user’s conn handle holds the terminal response — the same shape they see
after a redirect chain.
Setting a follow-up while one is already queued replaces the previous one
(last-writer-wins). Handlers that want to be polite about not clobbering a
follow-up queued by an earlier handler can peek via ConnExt::followup
or take via ConnExt::take_followup first.
An unrecovered error stash on the conn (see ConnExt::error and
ConnExt::take_error) wins over a queued follow-up: when the current cycle ends
with Err, the queued follow-up is discarded and the error propagates. Recovery
handlers that want the follow-up to run anyway (retry-on-error, stale-if-error
cache) must call take_error() inside after_response before queuing.
Sourcefn followup(&self) -> Option<&Conn>
fn followup(&self) -> Option<&Conn>
Borrow the queued follow-up Conn, if any, without consuming it.
Returns None when no follow-up has been installed. Useful for “polite”
composition — a handler that wants to avoid clobbering a follow-up queued by an
earlier handler in the chain can check this before calling
ConnExt::set_followup.
Sourcefn take_followup(&mut self) -> Option<Conn>
fn take_followup(&mut self) -> Option<Conn>
Detach the queued follow-up Conn, if any.
Pairs with ConnExt::set_followup for handlers that want to revoke or
inspect a follow-up queued by an earlier handler in the chain — e.g. take,
mutate, and re-queue, or take and discard outright.
Sourcefn error(&self) -> Option<&Error>
fn error(&self) -> Option<&Error>
Borrow the transport-level error stashed on this conn, if any.
During a handler chain’s after_response pass, this is Some when the network
round-trip failed (connect refused, TLS handshake error, malformed HTTP frame,
timeout, etc.). Observer handlers (logger, metrics) use this to record failures;
recovery handlers (stale-if-error cache, retry-with-fallback) use it as the
trigger to synthesize a fallback response and clear the error via
ConnExt::take_error.
Sourcefn set_error(&mut self, error: Error) -> &mut Self
fn set_error(&mut self, error: Error) -> &mut Self
Install a transport-level error on this conn.
Mostly internal — the framework stashes round-trip errors here automatically so
the handler chain’s after_response runs and can recover. Handler-authored use
is rare and usually means “synthesize a failure mode for a downstream recovery
handler to observe.”
Sourcefn take_error(&mut self) -> Option<Error>
fn take_error(&mut self) -> Option<Error>
Take the transport-level error stashed on this conn, leaving None in its place.
This is the recovery path: a handler that wants to convert a transport failure
into a synthetic success response (stale-if-error cache, retry-with-fallback)
calls this inside after_response to clear the stash before populating the
response state synthetically. If no handler clears the error, it propagates as
Err from the awaited conn.
Sourcefn halt(&mut self) -> &mut Self
fn halt(&mut self) -> &mut Self
Mark this conn halted, skipping the network round-trip in the current cycle.
Use this in combination with synthetic response state (ConnExt::set_status,
ConnExt::response_headers_mut, ConnExt::set_response_body) when a handler
wants to fully synthesize a response — cache hits, mocked responses, or
circuit-breaker short-circuits. The halt flag is internal to the handler chain and
is cleared on egress, so the user’s conn handle never observes residual halt state
after the awaited conn returns.
Sourcefn set_halted(&mut self, halted: bool) -> &mut Self
fn set_halted(&mut self, halted: bool) -> &mut Self
Set the halt flag explicitly.
Same semantics as ConnExt::halt for the affirmative case. The explicit
setter exists for the rare handler that wants to un-halt a conn another handler in
the chain has halted.
Sourcefn is_halted(&self) -> bool
fn is_halted(&self) -> bool
Whether this conn is halted within the current cycle.
after_response handlers can use this to differentiate “synthetic response” from
“transport-backed response” — e.g. a logger or metrics handler that wants to record
cache hits distinctly from network-backed responses.
Sourcefn set_response_body(&mut self, body: impl Into<Body>) -> &mut Self
fn set_response_body(&mut self, body: impl Into<Body>) -> &mut Self
Install an override response body, replacing whatever transport-backed body would otherwise be read from the network.
Used by handlers that synthesize responses — cache hits, mocked responses,
stale-if-error fallbacks. Typically combined with ConnExt::set_status,
ConnExt::response_headers_mut, and ConnExt::halt to construct a complete
synthetic response.
Accepts anything convertible to a Body, so common patterns work directly:
conn.set_response_body("hello");
conn.set_response_body(vec![1, 2, 3]);
conn.set_response_body(Body::new_streaming(file_reader, Some(file_size)));Encoding for ResponseBody::read_string is determined by the response headers’
Content-Type, just like a transport-backed body — set the appropriate header before
or after this call as needed. The user-set max_len is enforced for override bodies
as well as transport-backed ones.
Sourcefn with_response_body(self, body: impl Into<Body>) -> Selfwhere
Self: Sized,
fn with_response_body(self, body: impl Into<Body>) -> Selfwhere
Self: Sized,
Owned chainable variant of ConnExt::set_response_body.
Sourcefn set_status(&mut self, status: Status) -> &mut Self
fn set_status(&mut self, status: Status) -> &mut Self
Set the response status — handler-author synthesis.
Setting a status on a conn that’s about to be sent has no meaningful effect: the
status reflects what the server returned. The only sensible uses are inside a
handler synthesizing a response (cache hit, mocked response, stale-if-error
fallback) — pair with ConnExt::set_response_body,
ConnExt::response_headers_mut, and ConnExt::halt.
Sourcefn with_status(self, status: Status) -> Selfwhere
Self: Sized,
fn with_status(self, status: Status) -> Selfwhere
Self: Sized,
Owned chainable variant of ConnExt::set_status.
Sourcefn response_headers_mut(&mut self) -> &mut Headers
fn response_headers_mut(&mut self) -> &mut Headers
Mutably borrow the response headers — handler-author synthesis.
The read-only Conn::response_headers accessor stays inherent for user code that
wants to inspect what the server returned. Mutating those headers only makes sense
from inside a handler synthesizing a response.
Sourcefn set_response_headers(&mut self, response_headers: Headers) -> &mut Self
fn set_response_headers(&mut self, response_headers: Headers) -> &mut Self
Replace the response headers wholesale — handler-author synthesis.
Sourcefn response_trailers_mut(&mut self) -> Option<&mut Headers>
fn response_trailers_mut(&mut self) -> Option<&mut Headers>
Mutably borrow the response trailers, if any — handler-author synthesis.
Sourcefn set_response_trailers(&mut self, response_trailers: Headers) -> &mut Self
fn set_response_trailers(&mut self, response_trailers: Headers) -> &mut Self
Install response trailers — handler-author synthesis.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.