use std::num::NonZeroUsize;
use std::sync::{Arc, RwLock};
use std::thread::available_parallelism;
#[cfg(feature = "tls")]
use rustls::ServerConfig;
use crate::Result;
use super::{respond, ErrorHandler, Handler, HttpServer, HttpSettings, ResponseData};
#[derive(Clone, Debug)]
pub struct HttpServerBuilder<S: Send + Sync + 'static> {
addr: String,
settings: HttpSettings,
handler: Handler<S>,
error_handler: ErrorHandler<S>,
threads: usize,
#[cfg(feature = "tls")]
tls_config: Option<ServerConfig>,
}
impl<S: Send + Sync + 'static> Default for HttpServerBuilder<S> {
fn default() -> Self {
Self::new()
}
}
impl<S: Send + Sync + 'static> HttpServerBuilder<S> {
pub fn new() -> Self {
Self {
addr: "localhost:8080".to_string(),
threads: available_parallelism().unwrap_or(NonZeroUsize::MIN).get(),
settings: HttpSettings::default(),
handler: |_, _| unimplemented!(),
error_handler: |err, _| {
respond(
err.to_string(),
"text/plain",
ResponseData::internal_server_error().build(),
)
},
#[cfg(feature = "tls")]
tls_config: None,
}
}
pub fn addr(mut self, addr: impl ToString) -> Self {
self.addr = addr.to_string();
self
}
pub fn settings(mut self, settings: HttpSettings) -> Self {
self.settings = settings;
self
}
#[cfg(feature = "tls")]
pub fn tls(mut self, tls_config: Option<ServerConfig>) -> Self {
self.tls_config = tls_config;
self
}
#[cfg(feature = "tls")]
pub fn tls_on(self, tls_config: ServerConfig) -> Self {
self.tls(Some(tls_config))
}
#[cfg(feature = "tls")]
pub fn tls_off(self) -> Self {
self.tls(None)
}
pub fn handler(mut self, handler: Handler<S>) -> Self {
self.handler = handler;
self
}
pub fn error_handler(mut self, error_handler: ErrorHandler<S>) -> Self {
self.error_handler = error_handler;
self
}
pub fn threads(mut self, threads: usize) -> Self {
self.threads = threads;
self
}
pub fn build(self, shared: Arc<RwLock<S>>) -> Result<Arc<HttpServer<S>>> {
HttpServer::new(
self.addr,
Arc::new(self.settings),
self.handler,
self.error_handler,
shared,
self.threads,
#[cfg(feature = "tls")]
self.tls_config.map(Arc::new),
)
}
}