thruster_grpc/
server.rs

1use std::net::ToSocketAddrs;
2
3use hyper::service::{make_service_fn, service_fn};
4use hyper::{Body, Request, Response, Server};
5use std::sync::Arc;
6
7use thruster::context::hyper_request::HyperRequest;
8use thruster::{App, Context, ReusableBoxFuture, ThrusterServer};
9
10use crate::body::ProtoBody;
11
12pub struct ProtoServer<T: 'static + Context + Clone + Send + Sync, S: Send> {
13    app: App<HyperRequest, T, S>,
14}
15
16impl<
17        T: Context<Response = Response<ProtoBody>> + Clone + Send + Sync,
18        S: 'static + Send + Sync,
19    > ThrusterServer for ProtoServer<T, S>
20{
21    type Context = T;
22    type Response = Response<ProtoBody>;
23    type Request = HyperRequest;
24    type State = S;
25
26    fn new(app: App<Self::Request, T, Self::State>) -> Self {
27        ProtoServer { app }
28    }
29
30    fn build(mut self, host: &str, port: u16) -> ReusableBoxFuture<()> {
31        self.app = self.app.commit();
32
33        let arc_app = Arc::new(self.app);
34        let addr = (host, port).to_socket_addrs().unwrap().next().unwrap();
35
36        ReusableBoxFuture::new(async move {
37            let service = make_service_fn(|socket: &hyper::server::conn::AddrStream| {
38                let app = arc_app.clone();
39                let ip = socket.remote_addr().ip();
40
41                async move {
42                    Ok::<_, hyper::Error>(service_fn(move |req: Request<Body>| {
43                        let mut req = HyperRequest::new(req);
44                        req.ip = Some(ip);
45
46                        app.match_and_resolve(req)
47                    }))
48                }
49            });
50
51            let server = Server::bind(&addr).serve(service);
52
53            server.await.expect("Hyper server failed to start");
54        })
55    }
56}