use std::sync::{OnceLock, RwLock};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OpenApiResponseDesc {
pub status: u16,
pub description: &'static str,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OpenApiRouteSpec {
pub summary: Option<&'static str>,
pub tag: Option<&'static str>,
pub responses: &'static [OpenApiResponseDesc],
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RouteInfo {
pub method: &'static str,
pub path: &'static str,
pub handler: &'static str,
pub openapi: Option<&'static OpenApiRouteSpec>,
}
fn store() -> &'static RwLock<Vec<RouteInfo>> {
static STORE: OnceLock<RwLock<Vec<RouteInfo>>> = OnceLock::new();
STORE.get_or_init(|| RwLock::new(Vec::new()))
}
pub struct RouteRegistry;
impl RouteRegistry {
pub fn register(method: &'static str, path: &'static str, handler: &'static str) {
Self::register_spec(method, path, handler, None);
}
pub fn register_spec(
method: &'static str,
path: &'static str,
handler: &'static str,
openapi: Option<&'static OpenApiRouteSpec>,
) {
let mut guard = store().write().expect("route registry lock poisoned");
guard.push(RouteInfo {
method,
path,
handler,
openapi,
});
}
pub fn list() -> Vec<RouteInfo> {
let guard = store().read().expect("route registry lock poisoned");
guard.clone()
}
#[cfg(feature = "test-hooks")]
pub fn clear_for_tests() {
let mut guard = store().write().expect("route registry lock poisoned");
guard.clear();
}
}