turbomcp_server/routing/
bidirectional.rs1use turbomcp_protocol::RequestContext;
4use turbomcp_protocol::types::{
5 CreateMessageRequest, ElicitRequest, ElicitResult, ListRootsResult, PingRequest, PingResult,
6};
7
8use crate::{ServerError, ServerResult};
9
10use super::traits::ServerRequestDispatcher;
11
12pub struct BidirectionalRouter {
14 dispatcher: Option<std::sync::Arc<dyn ServerRequestDispatcher>>,
15}
16
17impl std::fmt::Debug for BidirectionalRouter {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 f.debug_struct("BidirectionalRouter")
20 .field("has_dispatcher", &self.dispatcher.is_some())
21 .finish()
22 }
23}
24
25impl BidirectionalRouter {
26 pub fn new() -> Self {
28 Self { dispatcher: None }
29 }
30
31 pub fn set_dispatcher<D>(&mut self, dispatcher: D)
33 where
34 D: ServerRequestDispatcher + 'static,
35 {
36 self.dispatcher = Some(std::sync::Arc::new(dispatcher));
37 }
38
39 pub fn get_dispatcher(&self) -> Option<&std::sync::Arc<dyn ServerRequestDispatcher>> {
41 self.dispatcher.as_ref()
42 }
43
44 pub fn supports_bidirectional(&self) -> bool {
46 self.dispatcher.is_some()
47 }
48
49 pub async fn send_elicitation_to_client(
51 &self,
52 request: ElicitRequest,
53 ctx: RequestContext,
54 ) -> ServerResult<ElicitResult> {
55 if let Some(dispatcher) = &self.dispatcher {
56 dispatcher.send_elicitation(request, ctx).await
57 } else {
58 Err(ServerError::Handler {
59 message: "Server request dispatcher not configured for bidirectional communication"
60 .to_string(),
61 context: Some("elicitation".to_string()),
62 })
63 }
64 }
65
66 pub async fn send_ping_to_client(
68 &self,
69 request: PingRequest,
70 ctx: RequestContext,
71 ) -> ServerResult<PingResult> {
72 if let Some(dispatcher) = &self.dispatcher {
73 dispatcher.send_ping(request, ctx).await
74 } else {
75 Err(ServerError::Handler {
76 message: "Server request dispatcher not configured for bidirectional communication"
77 .to_string(),
78 context: Some("ping".to_string()),
79 })
80 }
81 }
82
83 pub async fn send_create_message_to_client(
85 &self,
86 request: CreateMessageRequest,
87 ctx: RequestContext,
88 ) -> ServerResult<turbomcp_protocol::types::CreateMessageResult> {
89 if let Some(dispatcher) = &self.dispatcher {
90 dispatcher.send_create_message(request, ctx).await
91 } else {
92 Err(ServerError::Handler {
93 message: "Server request dispatcher not configured for bidirectional communication"
94 .to_string(),
95 context: Some("create_message".to_string()),
96 })
97 }
98 }
99
100 pub async fn send_list_roots_to_client(
102 &self,
103 request: turbomcp_protocol::types::ListRootsRequest,
104 ctx: RequestContext,
105 ) -> ServerResult<ListRootsResult> {
106 if let Some(dispatcher) = &self.dispatcher {
107 dispatcher.send_list_roots(request, ctx).await
108 } else {
109 Err(ServerError::Handler {
110 message: "Server request dispatcher not configured for bidirectional communication"
111 .to_string(),
112 context: Some("list_roots".to_string()),
113 })
114 }
115 }
116}
117
118impl Default for BidirectionalRouter {
119 fn default() -> Self {
120 Self::new()
121 }
122}
123
124impl Clone for BidirectionalRouter {
125 fn clone(&self) -> Self {
126 Self {
127 dispatcher: self.dispatcher.clone(),
128 }
129 }
130}