use crate::Route;
#[repr(C)]
pub struct RouteRegistration {
constructor: Option<fn() -> Route>,
}
impl RouteRegistration {
#[must_use]
pub const fn new(constructor: fn() -> Route) -> Self {
Self {
constructor: Some(constructor),
}
}
#[must_use]
pub const fn empty() -> Self {
Self { constructor: None }
}
}
#[must_use]
#[allow(unsafe_code)]
pub fn registered_routes() -> Vec<Route> {
let regs = unsafe { registrations() };
regs.iter()
.filter_map(|reg| reg.constructor)
.map(|ctor| ctor())
.collect()
}
#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))]
#[allow(unsafe_code)]
unsafe fn registrations() -> &'static [RouteRegistration] {
unsafe extern "C" {
static __start_fastapi_routes: u8;
static __stop_fastapi_routes: u8;
}
let start = unsafe { &__start_fastapi_routes as *const u8 as *const RouteRegistration };
let stop = unsafe { &__stop_fastapi_routes as *const u8 as *const RouteRegistration };
let count = (stop as usize - start as usize) / std::mem::size_of::<RouteRegistration>();
unsafe { std::slice::from_raw_parts(start, count) }
}
#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "freebsd")))]
#[allow(unsafe_code)]
unsafe fn registrations() -> &'static [RouteRegistration] {
&[]
}
#[used]
#[allow(unsafe_code)]
#[cfg_attr(
any(target_os = "linux", target_os = "android", target_os = "freebsd"),
unsafe(link_section = "fastapi_routes")
)]
static __FASTAPI_ROUTE_REGISTRY_ANCHOR: RouteRegistration = RouteRegistration::empty();