use typeway_core::ApiSpec;
use crate::handler_for::BoundHandler;
use crate::router::Router;
#[diagnostic::on_unimplemented(
message = "the handler tuple does not match the API specification `{A}`",
label = "handler tuple does not implement `Serves<{A}>`",
note = "each endpoint in the API type needs a corresponding `BoundHandler` created via `bind!(handler)`",
note = "the handler tuple must have exactly one `bind!(handler)` for each endpoint"
)]
pub trait Serves<A: ApiSpec> {
fn register(self, router: &mut Router);
}
macro_rules! impl_serves_for_tuple {
($(($E:ident, $idx:tt)),+) => {
impl<$($E: ApiSpec,)+> Serves<($($E,)+)> for ($(BoundHandler<$E>,)+) {
fn register(self, router: &mut Router) {
$(self.$idx.register_into(router);)+
}
}
};
}
impl_serves_for_tuple!((E0, 0));
impl_serves_for_tuple!((E0, 0), (E1, 1));
impl_serves_for_tuple!((E0, 0), (E1, 1), (E2, 2));
impl_serves_for_tuple!((E0, 0), (E1, 1), (E2, 2), (E3, 3));
impl_serves_for_tuple!((E0, 0), (E1, 1), (E2, 2), (E3, 3), (E4, 4));
impl_serves_for_tuple!((E0, 0), (E1, 1), (E2, 2), (E3, 3), (E4, 4), (E5, 5));
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16),
(E17, 17)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16),
(E17, 17),
(E18, 18)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16),
(E17, 17),
(E18, 18),
(E19, 19)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16),
(E17, 17),
(E18, 18),
(E19, 19),
(E20, 20)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16),
(E17, 17),
(E18, 18),
(E19, 19),
(E20, 20),
(E21, 21)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16),
(E17, 17),
(E18, 18),
(E19, 19),
(E20, 20),
(E21, 21),
(E22, 22)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16),
(E17, 17),
(E18, 18),
(E19, 19),
(E20, 20),
(E21, 21),
(E22, 22),
(E23, 23)
);
impl_serves_for_tuple!(
(E0, 0),
(E1, 1),
(E2, 2),
(E3, 3),
(E4, 4),
(E5, 5),
(E6, 6),
(E7, 7),
(E8, 8),
(E9, 9),
(E10, 10),
(E11, 11),
(E12, 12),
(E13, 13),
(E14, 14),
(E15, 15),
(E16, 16),
(E17, 17),
(E18, 18),
(E19, 19),
(E20, 20),
(E21, 21),
(E22, 22),
(E23, 23),
(E24, 24)
);
impl<B, C, R: ApiSpec, H: Serves<R>> Serves<typeway_core::versioning::VersionedApi<B, C, R>> for H {
fn register(self, router: &mut Router) {
<H as Serves<R>>::register(self, router)
}
}
pub struct SubApi<A: ApiSpec, H> {
handlers: H,
_api: std::marker::PhantomData<A>,
}
impl<A: ApiSpec, H> SubApi<A, H> {
pub fn new(handlers: H) -> Self {
SubApi {
handlers,
_api: std::marker::PhantomData,
}
}
}
impl<A: ApiSpec, H: Serves<A>> SubApi<A, H> {
pub fn register_into(self, router: &mut Router) {
self.handlers.register(router);
}
}
macro_rules! impl_serves_for_subapi_tuple {
($(($A:ident, $H:ident, $idx:tt)),+) => {
impl<$($A: ApiSpec, $H: Serves<$A>,)+> Serves<($($A,)+)> for ($(SubApi<$A, $H>,)+) {
fn register(self, router: &mut Router) {
$(self.$idx.register_into(router);)+
}
}
};
}
impl_serves_for_subapi_tuple!((A0, H0, 0), (A1, H1, 1));
impl_serves_for_subapi_tuple!((A0, H0, 0), (A1, H1, 1), (A2, H2, 2));
impl_serves_for_subapi_tuple!((A0, H0, 0), (A1, H1, 1), (A2, H2, 2), (A3, H3, 3));
impl_serves_for_subapi_tuple!(
(A0, H0, 0),
(A1, H1, 1),
(A2, H2, 2),
(A3, H3, 3),
(A4, H4, 4)
);
impl_serves_for_subapi_tuple!(
(A0, H0, 0),
(A1, H1, 1),
(A2, H2, 2),
(A3, H3, 3),
(A4, H4, 4),
(A5, H5, 5)
);
impl_serves_for_subapi_tuple!(
(A0, H0, 0),
(A1, H1, 1),
(A2, H2, 2),
(A3, H3, 3),
(A4, H4, 4),
(A5, H5, 5),
(A6, H6, 6)
);
impl_serves_for_subapi_tuple!(
(A0, H0, 0),
(A1, H1, 1),
(A2, H2, 2),
(A3, H3, 3),
(A4, H4, 4),
(A5, H5, 5),
(A6, H6, 6),
(A7, H7, 7)
);
impl_serves_for_subapi_tuple!(
(A0, H0, 0),
(A1, H1, 1),
(A2, H2, 2),
(A3, H3, 3),
(A4, H4, 4),
(A5, H5, 5),
(A6, H6, 6),
(A7, H7, 7),
(A8, H8, 8)
);
impl_serves_for_subapi_tuple!(
(A0, H0, 0),
(A1, H1, 1),
(A2, H2, 2),
(A3, H3, 3),
(A4, H4, 4),
(A5, H5, 5),
(A6, H6, 6),
(A7, H7, 7),
(A8, H8, 8),
(A9, H9, 9)
);