use crate::body::BoxBody;
use crate::error::Error;
use crate::handlers::Handlers;
use crate::server::HttpServer;
use crate::services::HttpService;
use crate::state::State;
use crate::traits::from_request::FromRequest;
use crate::traits::handler::Handler;
use crate::traits::responder::Responder;
use http::Method;
use std::fmt::Debug;
use std::future::Future;
use tokio::io;
use tokio::net::ToSocketAddrs;
use crate::prelude::{HttpPayload, HttpRequest, HttpResponse};
use crate::resource::RouteBuilder;
use crate::route::HandlerFn;
#[allow(unused_imports)]
use std::any::TypeId;
#[allow(unused_imports)]
use std::collections::HashMap;
use tower::layer::util::{Identity, Stack};
use tower::{Layer, Service, ServiceBuilder};
#[derive(Debug, Clone)]
pub struct HttpServerBuilder<T, L>
where
T: ToSocketAddrs + Default + Clone,
L: Layer<HandlerFn> + Clone + Send + 'static,
{
addr: Option<T>,
handlers: Handlers,
app_state: State,
service_builder: ServiceBuilder<L>,
}
impl<T: ToSocketAddrs + Default + Debug + Clone> Default for HttpServerBuilder<T, Identity> {
fn default() -> Self {
Self {
addr: None,
handlers: Handlers::new(),
app_state: State::new(),
service_builder: ServiceBuilder::new(),
}
}
}
impl<T: ToSocketAddrs + Default + Debug + Clone> HttpServerBuilder<T, Identity> {
pub(crate) fn new() -> HttpServerBuilder<T, Identity> {
Self::default()
}
}
impl<T, L> HttpServerBuilder<T, L>
where
T: ToSocketAddrs + Default + Debug + Clone,
L: Layer<HandlerFn> + Clone + Send + 'static,
L::Service: Service<(HttpRequest, HttpPayload), Response = HttpResponse, Error = Error>
+ Send
+ 'static,
<L::Service as Service<(HttpRequest, HttpPayload)>>::Future: Send + 'static,
{
pub fn app_state<S: Send + Sync + 'static>(self, state: S) -> Self {
self.app_state.insert(state);
self
}
pub fn service_method<H, Args>(mut self, method: Method, path: &str, handler: H) -> Self
where
H: Handler<Args> + Send + Sync + 'static,
Args: FromRequest + Send + 'static,
Args::Future: Future + Send + 'static,
H::Future: Future + Send + 'static,
H::Output: Responder<Body = BoxBody> + 'static,
Error: From<Args::Error>,
{
self.handlers.insert(method, path, handler);
self
}
pub fn service<H, Args>(mut self, handler: H) -> Self
where
H: HttpService<Args> + Handler<Args> + Send + Sync + 'static,
Args: FromRequest + Send + 'static,
Args::Future: Future + Send + 'static,
H::Future: Future + Send + 'static,
H::Output: Responder<Body = BoxBody> + 'static,
Error: From<Args::Error>,
{
self.handlers.insert(H::METHOD, H::PATH, handler);
self
}
pub fn route(mut self, route_builder: RouteBuilder) -> Self {
self.handlers.extend(route_builder.handlers());
self
}
pub fn bind(mut self, addr: T) -> Self {
self.addr = Some(addr);
self
}
pub async fn build(self) -> io::Result<HttpServer<L>> {
let addr = self.addr.unwrap_or_default();
HttpServer::new(addr, self.handlers, self.app_state, self.service_builder).await
}
pub fn wrap<S>(self, layer: S) -> HttpServerBuilder<T, Stack<S, L>>
where
S: Layer<HandlerFn> + Clone + Send + 'static,
L: Layer<S::Service> + Clone + Send + 'static,
{
HttpServerBuilder {
addr: self.addr,
handlers: self.handlers,
app_state: self.app_state,
service_builder: self.service_builder.layer(layer),
}
}
}