use std::any::Any;
use std::any::TypeId;
use std::sync::OnceLock;
pub use openapiv3::OpenAPI;
use crate::openapi::generate::generate_openapi;
pub use crate::openapi::metadata::OpenapiMetadata;
pub use crate::openapi::router_ext::OpenapiRouterExt;
mod generate;
mod metadata;
mod router_ext;
pub fn get_openapi() -> &'static OpenAPI {
static OPENAPI: OnceLock<OpenAPI> = OnceLock::new();
OPENAPI.get_or_init(|| OpenapiBuilder::default().build())
}
pub fn get_openapi_for_page(page: impl Any) -> OpenAPI {
OpenapiBuilder::default().page(page).build()
}
#[derive(Clone, Default)]
#[cfg_attr(doc, non_exhaustive)]
pub struct OpenapiBuilder {
pub omit_tags: bool,
#[doc(hidden)]
#[allow(private_interfaces)]
pub private: OpenapiBuilderPrivate,
}
#[derive(Clone, Default)]
struct OpenapiBuilderPrivate {
pages: Option<Vec<TypeId>>,
}
impl OpenapiBuilder {
pub fn page(&mut self, page: impl Any) -> &mut Self {
assert_eq!(
size_of_val(&page),
0,
"pages should be zero-sized marker types"
);
self.private
.pages
.get_or_insert_default()
.push(page.type_id());
self
}
pub fn build(&self) -> OpenAPI {
generate_openapi(self)
}
}