use crate::handler::{into_boxed_handler, BoxedHandler, Handler};
use http::Method;
use rustapi_openapi::Operation;
use std::collections::HashMap;
pub struct MethodRouter {
pub(super) handlers: HashMap<Method, BoxedHandler>,
pub(crate) operations: HashMap<Method, Operation>,
pub(crate) component_registrars: Vec<fn(&mut rustapi_openapi::OpenApiSpec)>,
}
impl Clone for MethodRouter {
fn clone(&self) -> Self {
Self {
handlers: self.handlers.clone(),
operations: self.operations.clone(),
component_registrars: self.component_registrars.clone(),
}
}
}
impl MethodRouter {
pub fn new() -> Self {
Self {
handlers: HashMap::new(),
operations: HashMap::new(),
component_registrars: Vec::new(),
}
}
fn on(
mut self,
method: Method,
handler: BoxedHandler,
operation: Operation,
component_registrar: fn(&mut rustapi_openapi::OpenApiSpec),
) -> Self {
self.handlers.insert(method.clone(), handler);
self.operations.insert(method, operation);
self.component_registrars.push(component_registrar);
self
}
pub(crate) fn get_handler(&self, method: &Method) -> Option<&BoxedHandler> {
self.handlers.get(method)
}
pub(crate) fn allowed_methods(&self) -> Vec<Method> {
self.handlers.keys().cloned().collect()
}
pub(crate) fn from_boxed(handlers: HashMap<Method, BoxedHandler>) -> Self {
Self {
handlers,
operations: HashMap::new(), component_registrars: Vec::new(),
}
}
pub(crate) fn insert_boxed_with_operation(
&mut self,
method: Method,
handler: BoxedHandler,
operation: Operation,
component_registrar: fn(&mut rustapi_openapi::OpenApiSpec),
) {
if self.handlers.contains_key(&method) {
panic!(
"Duplicate handler for method {} on the same path",
method.as_str()
);
}
self.handlers.insert(method.clone(), handler);
self.operations.insert(method, operation);
self.component_registrars.push(component_registrar);
}
pub fn get<H, T>(self, handler: H) -> Self
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
self.on(
Method::GET,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
pub fn post<H, T>(self, handler: H) -> Self
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
self.on(
Method::POST,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
pub fn put<H, T>(self, handler: H) -> Self
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
self.on(
Method::PUT,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
pub fn patch<H, T>(self, handler: H) -> Self
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
self.on(
Method::PATCH,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
pub fn delete<H, T>(self, handler: H) -> Self
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
self.on(
Method::DELETE,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
}
impl Default for MethodRouter {
fn default() -> Self {
Self::new()
}
}
pub fn get<H, T>(handler: H) -> MethodRouter
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
MethodRouter::new().on(
Method::GET,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
pub fn post<H, T>(handler: H) -> MethodRouter
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
MethodRouter::new().on(
Method::POST,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
pub fn put<H, T>(handler: H) -> MethodRouter
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
MethodRouter::new().on(
Method::PUT,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
pub fn patch<H, T>(handler: H) -> MethodRouter
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
MethodRouter::new().on(
Method::PATCH,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}
pub fn delete<H, T>(handler: H) -> MethodRouter
where
H: Handler<T>,
T: 'static,
{
let mut op = Operation::new();
H::update_operation(&mut op);
MethodRouter::new().on(
Method::DELETE,
into_boxed_handler(handler),
op,
<H as Handler<T>>::register_components,
)
}