pub struct MatchDispatchFrom<Counterpart: Role> { /* private fields */ }Expand description
Role-aware helper for pattern-matching on untyped JSON-RPC requests.
Prefer this over implementing HandleDispatchFrom directly. This provides
a more ergonomic API for matching on message types in connection handlers.
Use this when you need peer-aware transforms (e.g., unwrapping proxy envelopes)
before parsing messages. For simple parsing without peer awareness (e.g., inside
a callback), use MatchDispatch instead.
This wraps MatchDispatch and applies peer-specific message transformations
via remote_style().handle_incoming_dispatch() before delegating to MatchDispatch
for the actual parsing.
§Example
MatchDispatchFrom::new(message, cx)
.if_request(|req: InitializeRequest, responder: agent_client_protocol::Responder<InitializeResponse>| async move {
// Handle initialization
let response = InitializeResponse::new(req.protocol_version)
.agent_capabilities(AgentCapabilities::new());
responder.respond(response)
})
.await
.if_request(|_req: PromptRequest, responder: agent_client_protocol::Responder<PromptResponse>| async move {
// Handle prompts
responder.respond(PromptResponse::new(StopReason::EndTurn))
})
.await
.otherwise(|message| async move {
// Fallback for unrecognized messages
match message {
Dispatch::Request(_, responder) => responder.respond_with_error(agent_client_protocol::util::internal_error("unknown method")),
Dispatch::Notification(_) | Dispatch::Response(_, _) => Ok(()),
}
})
.awaitImplementations§
Source§impl<Counterpart: Role> MatchDispatchFrom<Counterpart>
impl<Counterpart: Role> MatchDispatchFrom<Counterpart>
Sourcepub fn new(message: Dispatch, cx: &ConnectionTo<Counterpart>) -> Self
pub fn new(message: Dispatch, cx: &ConnectionTo<Counterpart>) -> Self
Create a new pattern matcher for the given untyped request message.
Sourcepub async fn if_request<Req: JsonRpcRequest, H>(
self,
op: impl AsyncFnOnce(Req, Responder<Req::Response>) -> Result<H, Error>,
) -> Self
pub async fn if_request<Req: JsonRpcRequest, H>( self, op: impl AsyncFnOnce(Req, Responder<Req::Response>) -> Result<H, Error>, ) -> Self
Try to handle the message as a request of type Req.
If the message can be parsed as Req, the handler op is called with the parsed
request and a typed request context. If parsing fails or the message was already
handled by a previous handle_if, this call has no effect.
The handler can return either () (which becomes Handled::Yes) or an explicit
Handled value to control whether the message should be passed to the next handler.
Returns self to allow chaining multiple handle_if calls.
Sourcepub async fn if_request_from<Peer: Role, Req: JsonRpcRequest, H>(
self,
peer: Peer,
op: impl AsyncFnOnce(Req, Responder<Req::Response>) -> Result<H, Error>,
) -> Self
pub async fn if_request_from<Peer: Role, Req: JsonRpcRequest, H>( self, peer: Peer, op: impl AsyncFnOnce(Req, Responder<Req::Response>) -> Result<H, Error>, ) -> Self
Try to handle the message as a request of type Req from a specific peer.
This is similar to if_request, but first applies peer-specific
message transformation (e.g., unwrapping SuccessorMessage envelopes when receiving
from an agent via a proxy).
§Parameters
peer- The peer the message is expected to come fromop- The handler to call if the message matches
Sourcepub async fn if_notification<N: JsonRpcNotification, H>(
self,
op: impl AsyncFnOnce(N) -> Result<H, Error>,
) -> Selfwhere
Counterpart: HasPeer<Counterpart>,
H: IntoHandled<N>,
pub async fn if_notification<N: JsonRpcNotification, H>(
self,
op: impl AsyncFnOnce(N) -> Result<H, Error>,
) -> Selfwhere
Counterpart: HasPeer<Counterpart>,
H: IntoHandled<N>,
Try to handle the message as a notification of type N.
If the message can be parsed as N, the handler op is called with the parsed
notification and connection context. If parsing fails or the message was already
handled by a previous handle_if, this call has no effect.
The handler can return either () (which becomes Handled::Yes) or an explicit
Handled value to control whether the message should be passed to the next handler.
Returns self to allow chaining multiple handle_if calls.
Sourcepub async fn if_notification_from<Peer: Role, N: JsonRpcNotification, H>(
self,
peer: Peer,
op: impl AsyncFnOnce(N) -> Result<H, Error>,
) -> Selfwhere
Counterpart: HasPeer<Peer>,
H: IntoHandled<N>,
pub async fn if_notification_from<Peer: Role, N: JsonRpcNotification, H>(
self,
peer: Peer,
op: impl AsyncFnOnce(N) -> Result<H, Error>,
) -> Selfwhere
Counterpart: HasPeer<Peer>,
H: IntoHandled<N>,
Try to handle the message as a notification of type N from a specific peer.
This is similar to if_notification, but first applies peer-specific
message transformation (e.g., unwrapping SuccessorMessage envelopes when receiving
from an agent via a proxy).
§Parameters
peer- The peer the message is expected to come fromop- The handler to call if the message matches
Sourcepub async fn if_message_from<Peer: Role, Req: JsonRpcRequest, N: JsonRpcNotification, H>(
self,
peer: Peer,
op: impl AsyncFnOnce(Dispatch<Req, N>) -> Result<H, Error>,
) -> Self
pub async fn if_message_from<Peer: Role, Req: JsonRpcRequest, N: JsonRpcNotification, H>( self, peer: Peer, op: impl AsyncFnOnce(Dispatch<Req, N>) -> Result<H, Error>, ) -> Self
Try to handle the message as a typed Dispatch<Req, N> from a specific peer.
This is similar to MatchDispatch::if_message, but first applies peer-specific
message transformation (e.g., unwrapping SuccessorMessage envelopes).
§Parameters
peer- The peer the message is expected to come fromop- The handler to call if the message matches
Sourcepub async fn if_response_to<Req: JsonRpcRequest, H>(
self,
op: impl AsyncFnOnce(Result<Req::Response, Error>, ResponseRouter<Req::Response>) -> Result<H, Error>,
) -> Self
pub async fn if_response_to<Req: JsonRpcRequest, H>( self, op: impl AsyncFnOnce(Result<Req::Response, Error>, ResponseRouter<Req::Response>) -> Result<H, Error>, ) -> Self
Try to handle the message as a response to a request of type Req.
If the message is a Response variant and the method matches Req, the handler
is called with the result (which may be Ok or Err) and a typed response context.
Unlike requests and notifications, responses don’t need peer-specific transforms
(they don’t have the SuccessorMessage envelope structure), so this method
delegates directly to MatchDispatch::if_response_to.
Sourcepub async fn if_ok_response_to<Req: JsonRpcRequest, H>(
self,
op: impl AsyncFnOnce(Req::Response, ResponseRouter<Req::Response>) -> Result<H, Error>,
) -> Selfwhere
Counterpart: HasPeer<Counterpart>,
H: IntoHandled<(Req::Response, ResponseRouter<Req::Response>)>,
pub async fn if_ok_response_to<Req: JsonRpcRequest, H>(
self,
op: impl AsyncFnOnce(Req::Response, ResponseRouter<Req::Response>) -> Result<H, Error>,
) -> Selfwhere
Counterpart: HasPeer<Counterpart>,
H: IntoHandled<(Req::Response, ResponseRouter<Req::Response>)>,
Try to handle the message as a successful response to a request of type Req.
If the message is a Response variant with an Ok result and the method matches Req,
the handler is called with the parsed response and a typed response context.
Error responses are passed through without calling the handler.
This is a convenience wrapper around if_response_to.
Sourcepub async fn if_response_to_from<Req: JsonRpcRequest, Peer: Role, H>(
self,
peer: Peer,
op: impl AsyncFnOnce(Result<Req::Response, Error>, ResponseRouter<Req::Response>) -> Result<H, Error>,
) -> Selfwhere
Counterpart: HasPeer<Peer>,
H: IntoHandled<(Result<Req::Response, Error>, ResponseRouter<Req::Response>)>,
pub async fn if_response_to_from<Req: JsonRpcRequest, Peer: Role, H>(
self,
peer: Peer,
op: impl AsyncFnOnce(Result<Req::Response, Error>, ResponseRouter<Req::Response>) -> Result<H, Error>,
) -> Selfwhere
Counterpart: HasPeer<Peer>,
H: IntoHandled<(Result<Req::Response, Error>, ResponseRouter<Req::Response>)>,
Try to handle the message as a response to a request of type Req from a specific peer.
If the message is a Response variant, the method matches Req, and the role_id
matches the expected peer, the handler is called with the result and a typed response context.
This is used to filter responses by the peer they came from, which is important in proxy scenarios where responses might arrive from multiple peers.
Sourcepub async fn if_ok_response_to_from<Req: JsonRpcRequest, Peer: Role, H>(
self,
peer: Peer,
op: impl AsyncFnOnce(Req::Response, ResponseRouter<Req::Response>) -> Result<H, Error>,
) -> Self
pub async fn if_ok_response_to_from<Req: JsonRpcRequest, Peer: Role, H>( self, peer: Peer, op: impl AsyncFnOnce(Req::Response, ResponseRouter<Req::Response>) -> Result<H, Error>, ) -> Self
Try to handle the message as a successful response to a request of type Req from a specific peer.
This is a convenience wrapper around if_response_to_from
for the common case where you only care about successful responses.
Sourcepub fn done(self) -> Result<Handled<Dispatch>, Error>
pub fn done(self) -> Result<Handled<Dispatch>, Error>
Complete matching, returning Handled::No if no match was found.
Sourcepub async fn otherwise(
self,
op: impl AsyncFnOnce(Dispatch) -> Result<(), Error>,
) -> Result<(), Error>
pub async fn otherwise( self, op: impl AsyncFnOnce(Dispatch) -> Result<(), Error>, ) -> Result<(), Error>
Handle messages that didn’t match any previous handle_if call.
This is the fallback handler that receives the original untyped message if none of the typed handlers matched. You must call this method to complete the pattern matching chain and get the final result.
Sourcepub async fn otherwise_delegate(
self,
handler: impl HandleDispatchFrom<Counterpart>,
) -> Result<Handled<Dispatch>, Error>
pub async fn otherwise_delegate( self, handler: impl HandleDispatchFrom<Counterpart>, ) -> Result<Handled<Dispatch>, Error>
Handle messages that didn’t match any previous handle_if call.
This is the fallback handler that receives the original untyped message if none of the typed handlers matched. You must call this method to complete the pattern matching chain and get the final result.