use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use std::collections::BTreeMap;
pub type Any = serde_json::Value;
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Referenceable<T> {
Data(T),
Reference(Reference),
}
impl<T> Referenceable<T> {
pub fn data(data: T) -> Self {
Self::Data(data)
}
pub fn reference(reference: impl Into<String>) -> Self {
Self::Reference(Reference::new(reference))
}
pub fn component_ref(component_type: &str, name: impl Into<String>) -> Self {
Self::Reference(Reference::new(format!("#/components/{}/{}", component_type, name.into())))
}
pub fn as_data(&self) -> Option<&T> {
match self {
Self::Data(data) => Some(data),
Self::Reference(_) => None,
}
}
pub fn as_reference(&self) -> Option<&Reference> {
match self {
Self::Data(_) => None,
Self::Reference(ref_) => Some(ref_),
}
}
pub fn is_data(&self) -> bool {
matches!(self, Self::Data(_))
}
pub fn is_reference(&self) -> bool {
matches!(self, Self::Reference(_))
}
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenAPIV3 {
pub openapi: String,
pub info: Info,
pub servers: Option<Vec<Server>>,
pub paths: BTreeMap<String, PathItem>,
pub components: Option<Components>,
pub security: Option<Vec<SecurityRequirement>>,
pub tags: Option<Vec<Tag>>,
pub external_docs: Option<ExternalDocumentation>,
#[serde(flatten)]
pub extras: Option<BTreeMap<String, Any>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Info {
pub title: String,
pub description: Option<String>,
pub terms_of_service: Option<String>,
pub contact: Option<Contact>,
pub license: Option<License>,
pub version: String,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Contact {
pub name: Option<String>,
pub url: Option<String>,
pub email: Option<String>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct License {
pub name: String,
pub url: Option<String>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Server {
pub url: String,
pub description: Option<String>,
pub variables: Option<BTreeMap<String, ServerVariable>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerVariable {
#[serde(rename = "enum")]
pub _enum: Option<Vec<String>>,
pub default: String,
pub description: Option<String>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Components {
pub schemas: Option<BTreeMap<String, Referenceable<Schema>>>,
pub responses: Option<BTreeMap<String, Referenceable<Response>>>,
pub parameters: Option<BTreeMap<String, Referenceable<Parameter>>>,
pub examples: Option<BTreeMap<String, Referenceable<Example>>>,
pub request_bodies: Option<BTreeMap<String, Referenceable<RequestBody>>>,
pub headers: Option<BTreeMap<String, Referenceable<Header>>>,
pub security_schemes: Option<BTreeMap<String, Referenceable<SecurityScheme>>>,
pub links: Option<BTreeMap<String, Referenceable<Link>>>,
pub callbacks: Option<BTreeMap<String, Referenceable<Callback>>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PathItem {
#[serde(rename = "$ref")]
pub _ref: Option<String>,
pub summary: Option<String>,
pub description: Option<String>,
pub get: Option<Operation>,
pub put: Option<Operation>,
pub post: Option<Operation>,
pub delete: Option<Operation>,
pub options: Option<Operation>,
pub head: Option<Operation>,
pub patch: Option<Operation>,
pub trace: Option<Operation>,
pub servers: Option<Vec<Server>>,
pub parameters: Option<Vec<Referenceable<Parameter>>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Operation {
pub tags: Option<Vec<String>>,
pub summary: Option<String>,
pub description: Option<String>,
pub external_docs: Option<ExternalDocumentation>,
pub operation_id: Option<String>,
pub parameters: Option<Vec<Referenceable<Parameter>>>,
pub request_body: Option<Referenceable<RequestBody>>,
pub responses: Responses,
pub callbacks: Option<BTreeMap<String, Referenceable<Callback>>>,
pub deprecated: Option<bool>,
pub security: Option<Vec<SecurityRequirement>>,
pub servers: Option<Vec<Server>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalDocumentation {
pub description: Option<String>,
pub url: String,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ParameterIn {
Query,
Header,
Path,
Cookie,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Parameter {
pub name: String,
#[serde(alias = "in")]
pub _in: ParameterIn,
pub description: Option<String>,
pub required: Option<bool>,
pub deprecated: Option<bool>,
pub allow_empty_value: Option<bool>,
pub style: Option<String>,
pub explode: Option<bool>,
pub allow_reserved: Option<bool>,
pub schema: Option<Referenceable<Schema>>,
pub example: Option<Any>,
pub examples: Option<BTreeMap<String, Referenceable<Example>>>,
pub content: Option<BTreeMap<String, MediaType>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RequestBody {
pub description: Option<String>,
pub required: Option<bool>,
pub content: BTreeMap<String, MediaType>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MediaType {
pub schema: Option<Referenceable<Schema>>,
pub example: Option<Any>,
pub examples: Option<BTreeMap<String, Referenceable<Example>>>,
pub encoding: Option<BTreeMap<String, Encoding>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Encoding {
pub content_type: Option<String>,
pub headers: Option<BTreeMap<String, Referenceable<Header>>>,
pub style: Option<String>,
pub explode: Option<bool>,
pub allow_reserved: Option<bool>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Responses {
pub default: Option<Referenceable<Response>>,
#[serde(flatten)]
pub data: BTreeMap<String, Referenceable<Response>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Response {
pub description: String,
pub headers: Option<BTreeMap<String, Referenceable<Header>>>,
pub content: Option<BTreeMap<String, MediaType>>,
pub links: Option<BTreeMap<String, Referenceable<Link>>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Callback {
#[serde(flatten)]
pub data: BTreeMap<String, PathItem>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Example {
pub summary: Option<String>,
pub description: Option<String>,
pub value: Option<Any>,
pub external_value: Option<String>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Link {
pub operation_ref: Option<String>,
pub operation_id: String,
pub parameters: Option<BTreeMap<String, Any>>,
pub request_body: Option<Any>,
pub description: Option<String>,
pub server: Option<Server>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Header {
pub description: Option<String>,
pub required: Option<bool>,
pub deprecated: Option<bool>,
pub allow_empty_value: Option<bool>,
pub style: Option<String>,
pub explode: Option<bool>,
pub allow_reserved: Option<bool>,
pub schema: Option<Referenceable<Schema>>,
pub example: Option<Any>,
pub examples: Option<BTreeMap<String, Referenceable<Example>>>,
pub content: Option<BTreeMap<String, MediaType>>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Tag {
pub name: String,
pub description: Option<String>,
pub external_docs: Option<ExternalDocumentation>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Reference {
#[serde(rename = "$ref")]
pub _ref: String,
}
impl Reference {
pub fn new(reference: impl Into<String>) -> Self {
Self {
_ref: reference.into(),
}
}
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Schema {
#[serde(rename = "type")]
pub _type: Option<String>,
pub format: Option<String>,
pub nullable: Option<bool>,
pub description: Option<String>,
#[serde(flatten)]
pub extras: BTreeMap<String, Any>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Discriminator {
pub property_name: String,
pub maapping: Option<BTreeMap<String, String>>,
}
use crate::security::{SecurityRequirement, SecurityScheme};