shuttle_tower/
lib.rs

1#![doc = include_str!("../README.md")]
2use shuttle_runtime::{CustomError, Error};
3use std::net::SocketAddr;
4
5pub use tower;
6
7/// A wrapper type for [tower::Service] so we can implement [shuttle_runtime::Service] for it.
8pub struct TowerService<T>(pub T);
9
10#[shuttle_runtime::async_trait]
11impl<T> shuttle_runtime::Service for TowerService<T>
12where
13    T: tower::Service<hyper::Request<hyper::Body>, Response = hyper::Response<hyper::Body>>
14        + Clone
15        + Send
16        + Sync
17        + 'static,
18    T::Error: std::error::Error + Send + Sync,
19    T::Future: std::future::Future + Send + Sync,
20{
21    /// Takes the service that is returned by the user in their [shuttle_runtime::main] function
22    /// and binds to an address passed in by shuttle.
23    async fn bind(mut self, addr: SocketAddr) -> Result<(), Error> {
24        let shared = tower::make::Shared::new(self.0);
25        hyper::Server::bind(&addr)
26            .serve(shared)
27            .await
28            .map_err(CustomError::new)?;
29
30        Ok(())
31    }
32}
33
34impl<T> From<T> for TowerService<T>
35where
36    T: tower::Service<hyper::Request<hyper::Body>, Response = hyper::Response<hyper::Body>>
37        + Clone
38        + Send
39        + Sync
40        + 'static,
41    T::Error: std::error::Error + Send + Sync,
42    T::Future: std::future::Future + Send + Sync,
43{
44    fn from(service: T) -> Self {
45        Self(service)
46    }
47}
48
49#[doc = include_str!("../README.md")]
50pub type ShuttleTower<T> = Result<TowerService<T>, Error>;