use crate::Section;
use indexmap::IndexMap;
use openapiv3::{
Callback, Example, Header, Link, OpenAPI, Parameter, PathItem, ReferenceOr, RequestBody,
Response, Schema, SecurityScheme,
};
pub trait Component: sealed::Sealed + Sized {
const SECTION: Section;
fn section(openapi: &OpenAPI) -> Option<&IndexMap<String, ReferenceOr<Self>>>;
}
mod sealed {
pub trait Sealed {}
}
macro_rules! component {
($ty:ty, $section:ident, $field:ident) => {
impl sealed::Sealed for $ty {}
impl Component for $ty {
const SECTION: Section = Section::$section;
fn section(openapi: &OpenAPI) -> Option<&IndexMap<String, ReferenceOr<Self>>> {
Some(&openapi.components.as_ref()?.$field)
}
}
};
}
component!(Callback, Callbacks, callbacks);
component!(Example, Examples, examples);
component!(Header, Headers, headers);
component!(Link, Links, links);
component!(Parameter, Parameters, parameters);
component!(RequestBody, RequestBodies, request_bodies);
component!(Response, Responses, responses);
component!(Schema, Schemas, schemas);
component!(SecurityScheme, SecuritySchemes, security_schemes);
impl sealed::Sealed for PathItem {}
impl Component for PathItem {
const SECTION: Section = Section::Paths;
fn section(openapi: &OpenAPI) -> Option<&IndexMap<String, ReferenceOr<Self>>> {
Some(&openapi.paths.paths)
}
}