rama_net/client/
either_conn.rs

1use rama_core::Context;
2use rama_core::Service;
3use rama_core::combinators::{define_either, impl_async_read_write_either, impl_iterator_either};
4use rama_core::error::BoxError;
5use std::fmt;
6use std::io::IoSlice;
7use std::pin::Pin;
8use std::task::{Context as TaskContext, Poll};
9use tokio::io::{AsyncRead, AsyncWrite, Error as IoError, ReadBuf, Result as IoResult};
10
11/// `EitherConn` can be used like you would normally use `Either`, but works with different
12/// return types, which is needed when combining different connectors.
13macro_rules! impl_either_conn {
14    ($macro:ident) => {
15        $macro!(EitherConn, A, B,);
16        $macro!(EitherConn3, A, B, C,);
17        $macro!(EitherConn4, A, B, C, D,);
18        $macro!(EitherConn5, A, B, C, D, E,);
19        $macro!(EitherConn6, A, B, C, D, E, F,);
20        $macro!(EitherConn7, A, B, C, D, E, F, G,);
21        $macro!(EitherConn8, A, B, C, D, E, F, G, H,);
22        $macro!(EitherConn9, A, B, C, D, E, F, G, H, I,);
23    };
24}
25
26impl_either_conn!(define_either);
27impl_either_conn!(impl_iterator_either);
28
29use crate::client::EstablishedClientConnection;
30
31macro_rules! impl_service_either_conn {
32    ($id:ident, $($param:ident),+ $(,)?) => {
33        rama_macros::paste! {
34            impl<$($param, [<Conn $param>]),+, State, Request> Service<State, Request> for $id<$($param),+>
35            where
36                $(
37                    $param: Service<
38                        State,
39                        Request,
40                        Response = EstablishedClientConnection<[<Conn $param>], State, Request>,
41                        Error: Into<BoxError>,
42                    >,
43                    [<Conn $param>]: Send + 'static,
44                )+
45                Request: Send + 'static,
46                State: Clone + Send + Sync + 'static,
47
48            {
49                type Response = EstablishedClientConnection<[<$id Connected>]<$([<Conn $param>]),+,>, State, Request>;
50                type Error = BoxError;
51
52                async fn serve(&self, ctx: Context<State>, req: Request) -> Result<Self::Response, Self::Error> {
53                    match self {
54                        $(
55                            $id::$param(s) => {
56                                let resp = s.serve(ctx, req).await.map_err(Into::into)?;
57                                Ok(EstablishedClientConnection {
58                                    conn: [<$id Connected>]::$param(resp.conn),
59                                    ctx: resp.ctx,
60                                    req: resp.req,
61                                })
62                            },
63                        )+
64                    }
65                }
66            }
67        }
68    };
69}
70
71impl_either_conn!(impl_service_either_conn);
72
73/// `EitherConnConnected` is created when `EitherConn` has been connected and we now have an actual
74/// connection instead of a connector
75macro_rules! impl_either_conn_connected {
76    ($macro:ident) => {
77        $macro!(EitherConnConnected, A, B,);
78        $macro!(EitherConn3Connected, A, B, C,);
79        $macro!(EitherConn4Connected, A, B, C, D,);
80        $macro!(EitherConn5Connected, A, B, C, D, E,);
81        $macro!(EitherConn6Connected, A, B, C, D, E, F,);
82        $macro!(EitherConn7Connected, A, B, C, D, E, F, G,);
83        $macro!(EitherConn8Connected, A, B, C, D, E, F, G, H,);
84        $macro!(EitherConn9Connected, A, B, C, D, E, F, G, H, I,);
85    };
86}
87
88impl_either_conn_connected!(define_either);
89impl_either_conn_connected!(impl_async_read_write_either);
90impl_either_conn_connected!(impl_iterator_either);
91
92macro_rules! impl_service_either_conn_connected {
93    ($id:ident, $($param:ident),+ $(,)?) => {
94        impl<$($param),+, State, Request, Response> Service<State, Request> for $id<$($param),+>
95        where
96            $(
97                $param: Service<State, Request, Response = Response, Error: Into<BoxError>>,
98            )+
99            Request: Send + 'static,
100            State: Clone + Send + Sync + 'static,
101            Response: Send + 'static,
102        {
103            type Response = Response;
104            type Error = BoxError;
105
106            async fn serve(&self, ctx: Context<State>, req: Request) -> Result<Self::Response, Self::Error> {
107                match self {
108                    $(
109                        $id::$param(s) => s.serve(ctx, req).await.map_err(Into::into),
110                    )+
111                }
112            }
113        }
114    };
115}
116
117impl_either_conn_connected!(impl_service_either_conn_connected);