use crate::{Response, TypeSystemBuilder};
use std::sync::Arc;
use std::time::Duration;
pub struct ServerBuilder {
type_system: TypeSystemBuilder,
routers: Vec<Box<dyn Router>>,
error_handler: ErrorHandler,
not_found_handler: NotFoundHandler,
max_head_buffer_size: usize,
connection_timeout: Option<Duration>,
read_timeout: Option<Duration>,
keep_alive_timeout: Option<Duration>,
request_body_io_timeout: Option<Duration>,
write_timeout: Option<Duration>,
continue_handler: ContinueHandler,
}
use crate::default_functions::{
default_continue_handler, default_error_handler, default_fallback_not_found_handler,
};
pub use crate::functional_traits::*;
use crate::tii_error::{TiiError, TiiResult, UserError};
use crate::tii_router::Routeable;
use crate::tii_router_builder::RouterBuilder;
use crate::tii_server::Server;
use crate::RequestContext;
pub type ErrorHandler = fn(&mut RequestContext, TiiError) -> TiiResult<Response>;
pub type NotRouteableHandler = fn(&mut RequestContext, &[Routeable]) -> TiiResult<Response>;
pub type NotFoundHandler = fn(&mut RequestContext) -> TiiResult<Response>;
impl Default for ServerBuilder {
fn default() -> Self {
Self {
type_system: TypeSystemBuilder::default(),
routers: Vec::new(),
error_handler: default_error_handler,
not_found_handler: default_fallback_not_found_handler,
connection_timeout: None,
max_head_buffer_size: 8192,
keep_alive_timeout: None,
read_timeout: None,
request_body_io_timeout: None,
write_timeout: None,
continue_handler: default_continue_handler,
}
}
}
impl ServerBuilder {
pub fn builder<T: FnOnce(ServerBuilder) -> TiiResult<ServerBuilder>>(
closure: T,
) -> TiiResult<Server> {
closure(ServerBuilder::default()).map(|builder| builder.build())
}
pub fn builder_arc<T: FnOnce(ServerBuilder) -> TiiResult<ServerBuilder>>(
closure: T,
) -> TiiResult<Arc<Server>> {
closure(ServerBuilder::default()).map(|builder| builder.build_arc())
}
pub fn build(self) -> Server {
Server::new(
self.type_system,
self.routers,
self.error_handler,
self.not_found_handler,
self.max_head_buffer_size,
self.connection_timeout,
self.read_timeout,
self.keep_alive_timeout,
self.request_body_io_timeout,
self.write_timeout,
self.continue_handler,
)
}
pub fn build_arc(self) -> Arc<Server> {
Arc::new(self.build())
}
pub fn type_system(mut self, configurator: impl FnOnce(&mut TypeSystemBuilder)) -> Self {
configurator(&mut self.type_system);
self
}
pub fn with_router(mut self, handler: impl Router + 'static) -> Self {
self.routers.push(Box::new(handler));
self
}
pub fn router<T: FnOnce(RouterBuilder) -> TiiResult<RouterBuilder>>(
self,
builder: T,
) -> TiiResult<Self> {
Ok(self.with_router(builder(RouterBuilder::default())?.build()))
}
pub fn with_error_handler(mut self, handler: ErrorHandler) -> TiiResult<Self> {
self.error_handler = handler;
Ok(self)
}
pub fn with_not_found_handler(mut self, handler: NotFoundHandler) -> TiiResult<Self> {
self.not_found_handler = handler;
Ok(self)
}
pub fn with_max_head_buffer_size(mut self, size: usize) -> TiiResult<Self> {
if size < 0x100 {
return Err(UserError::RequestHeadBufferTooSmall(size).into());
}
self.max_head_buffer_size = size;
Ok(self)
}
pub fn with_connection_timeout(mut self, timeout: Option<Duration>) -> TiiResult<Self> {
self.connection_timeout = timeout;
Ok(self)
}
pub fn with_read_timeout(mut self, timeout: Option<Duration>) -> TiiResult<Self> {
self.read_timeout = timeout;
Ok(self)
}
pub fn with_write_timeout(mut self, timeout: Option<Duration>) -> TiiResult<Self> {
self.write_timeout = timeout;
Ok(self)
}
pub fn with_keep_alive_timeout(mut self, timeout: Option<Duration>) -> TiiResult<Self> {
self.keep_alive_timeout = timeout;
Ok(self)
}
pub fn with_request_body_timeout(mut self, timeout: Option<Duration>) -> TiiResult<Self> {
self.request_body_io_timeout = timeout;
Ok(self)
}
pub fn ok(self) -> TiiResult<Self> {
Ok(self)
}
}