use core::fmt;
use std::collections::HashSet;
use super::collection::RouteCollection;
use crate::state;
pub struct Router<UserState> {
pub name: String,
pub fullpath: String,
pub methods: HashSet<axum::http::Method>,
pub action: Option<axum::routing::MethodRouter<state::State<UserState>>>,
}
impl<US> Router<US> {
pub fn path(path: impl ToString + fmt::Debug) -> Self {
let name = format!("{path:?}");
Self {
name,
fullpath: path.to_string(),
action: Default::default(),
methods: Default::default(),
}
}
pub fn any<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
self.action.replace(axum::routing::any(action));
self.methods.extend([
axum::http::Method::DELETE,
axum::http::Method::GET,
axum::http::Method::HEAD,
axum::http::Method::OPTIONS,
axum::http::Method::PATCH,
axum::http::Method::POST,
axum::http::Method::PUT,
axum::http::Method::TRACE,
]);
self
}
pub fn delete<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
if let Some(current_action) = self.action.take() {
self.action.replace(current_action.delete(action));
} else {
self.action.replace(axum::routing::delete(action));
}
self.methods.insert(axum::http::Method::DELETE);
self
}
pub fn get<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
if let Some(current_action) = self.action.take() {
self.action.replace(current_action.get(action));
} else {
self.action.replace(axum::routing::get(action));
}
self.methods.insert(axum::http::Method::GET);
self
}
pub fn head<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
if let Some(current_action) = self.action.take() {
self.action.replace(current_action.head(action));
} else {
self.action.replace(axum::routing::head(action));
}
self.methods.insert(axum::http::Method::HEAD);
self
}
pub fn options<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
if let Some(current_action) = self.action.take() {
self.action.replace(current_action.options(action));
} else {
self.action.replace(axum::routing::options(action));
}
self.methods.insert(axum::http::Method::OPTIONS);
self
}
pub fn patch<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
if let Some(current_action) = self.action.take() {
self.action.replace(current_action.patch(action));
} else {
self.action.replace(axum::routing::patch(action));
}
self.methods.insert(axum::http::Method::PATCH);
self
}
pub fn post<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
if let Some(current_action) = self.action.take() {
self.action.replace(current_action.post(action));
} else {
self.action.replace(axum::routing::post(action));
}
self.methods.insert(axum::http::Method::POST);
self
}
pub fn put<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
if let Some(current_action) = self.action.take() {
self.action.replace(current_action.put(action));
} else {
self.action.replace(axum::routing::put(action));
}
self.methods.insert(axum::http::Method::PUT);
self
}
pub fn trace<Action, ActionType>(mut self, action: Action) -> Self
where
Action: axum::handler::Handler<ActionType, state::State<US>>,
ActionType: 'static,
US: 'static,
US: Clone,
US: Send + Sync,
{
if let Some(current_action) = self.action.take() {
self.action.replace(current_action.trace(action));
} else {
self.action.replace(axum::routing::trace(action));
}
self.methods.insert(axum::http::Method::TRACE);
self
}
}
macro_rules! router_impl {
(
impl RouterInterface for
$(
| ( $($generic:ident),* )
)* {}
) => {
$(
impl<State, $($generic),*> super::interface::RouterExt for ($($generic),*)
where
State: crate::state::StateInterface,
$(
$generic: super::interface::RouterExt<State = State>,
)*
{
type State = State;
fn routes() -> RouteCollection<Self::State> {
let mut router_collection = Self::router_collection();
$( router_collection.extend($generic::routes()); )*
router_collection
}
}
)*
};
}
router_impl! {
impl RouterInterface for
| (A, B)
| (A, B, C)
| (A, B, C, D)
| (A, B, C, D, E)
| (A, B, C, D, E, F)
| (A, B, C, D, E, F, G)
| (A, B, C, D, E, F, G, H)
| (A, B, C, D, E, F, G, H, I)
| (A, B, C, D, E, F, G, H, I, J)
| (A, B, C, D, E, F, G, H, I, J, K)
| (A, B, C, D, E, F, G, H, I, J, K, L)
| (A, B, C, D, E, F, G, H, I, J, K, L, M)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y)
| (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)
{}
}