1use rama_core::{Context, Service, error::BoxError, service::BoxService};
2use std::fmt;
3
4pub struct EstablishedClientConnection<S, State, Request> {
6 pub ctx: Context<State>,
8 pub req: Request,
10 pub conn: S,
12}
13
14impl<S: fmt::Debug, State: fmt::Debug, Request: fmt::Debug> fmt::Debug
15 for EstablishedClientConnection<S, State, Request>
16{
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 f.debug_struct("EstablishedClientConnection")
19 .field("ctx", &self.ctx)
20 .field("req", &self.req)
21 .field("conn", &self.conn)
22 .finish()
23 }
24}
25
26impl<S: Clone, State: Clone, Request: Clone> Clone
27 for EstablishedClientConnection<S, State, Request>
28{
29 fn clone(&self) -> Self {
30 Self {
31 ctx: self.ctx.clone(),
32 req: self.req.clone(),
33 conn: self.conn.clone(),
34 }
35 }
36}
37
38pub trait ConnectorService<State, Request>: Send + Sync + 'static {
44 type Connection;
46 type Error: Into<BoxError>;
48
49 fn connect(
52 &self,
53 ctx: Context<State>,
54 req: Request,
55 ) -> impl Future<
56 Output = Result<EstablishedClientConnection<Self::Connection, State, Request>, Self::Error>,
57 > + Send
58 + '_;
59}
60
61impl<S, State, Request, Connection> ConnectorService<State, Request> for S
62where
63 S: Service<
64 State,
65 Request,
66 Response = EstablishedClientConnection<Connection, State, Request>,
67 Error: Into<BoxError>,
68 >,
69{
70 type Connection = Connection;
71 type Error = S::Error;
72
73 fn connect(
74 &self,
75 ctx: Context<State>,
76 req: Request,
77 ) -> impl Future<
78 Output = Result<EstablishedClientConnection<Self::Connection, State, Request>, Self::Error>,
79 > + Send
80 + '_ {
81 self.serve(ctx, req)
82 }
83}
84
85pub struct BoxedConnectorService<S>(S);
88
89impl<S> BoxedConnectorService<S> {
90 pub fn new(connector: S) -> Self {
92 Self(connector)
93 }
94}
95
96impl<S: fmt::Debug> fmt::Debug for BoxedConnectorService<S> {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 f.debug_tuple("BoxedConnectorService")
99 .field(&self.0)
100 .finish()
101 }
102}
103
104impl<S: Clone> Clone for BoxedConnectorService<S> {
105 fn clone(&self) -> Self {
106 Self(self.0.clone())
107 }
108}
109
110impl<S, State, Request, Svc> Service<State, Request> for BoxedConnectorService<S>
111where
112 S: Service<
113 State,
114 Request,
115 Response = EstablishedClientConnection<Svc, State, Request>,
116 Error: Into<BoxError>,
117 >,
118 Svc: Service<State, Request>,
119 State: Send + 'static,
120 Request: Send + 'static,
121{
122 type Response = EstablishedClientConnection<
123 BoxService<State, Request, Svc::Response, Svc::Error>,
124 State,
125 Request,
126 >;
127 type Error = S::Error;
128
129 async fn serve(
130 &self,
131 ctx: Context<State>,
132 req: Request,
133 ) -> Result<Self::Response, Self::Error> {
134 let EstablishedClientConnection {
135 ctx,
136 req,
137 conn: svc,
138 } = self.0.serve(ctx, req).await?;
139 Ok(EstablishedClientConnection {
140 ctx,
141 req,
142 conn: svc.boxed(),
143 })
144 }
145}