use indexmap::IndexMap;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiDocument {
pub openapi: String,
pub info: OpenApiInfo,
#[serde(skip_serializing_if = "Option::is_none")]
pub servers: Option<Vec<OpenApiServer>>,
pub paths: IndexMap<String, IndexMap<String, OpenApiOperation>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub components: Option<OpenApiComponents>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiInfo {
pub title: String,
pub version: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiServer {
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiComponents {
pub schemas: IndexMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub enum OpenApiSchemaRef {
Ref {
#[serde(rename = "$ref")]
ref_path: String,
},
Inline(serde_json::Value),
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiParameter {
pub name: String,
#[serde(rename = "in")]
pub location: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub required: bool,
pub schema: OpenApiSchemaRef,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiRequestBody {
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub required: bool,
pub content: IndexMap<String, OpenApiMediaType>,
}
#[derive(Debug, Clone, Serialize)]
pub struct OpenApiMediaType {
pub schema: OpenApiSchemaRef,
}
#[derive(Debug, Clone, Serialize)]
pub struct OpenApiResponses {
#[serde(flatten)]
pub statuses: IndexMap<String, OpenApiResponse>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiResponse {
pub description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<IndexMap<String, OpenApiMediaType>>,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenApiOperation {
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub operation_id: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub parameters: Vec<OpenApiParameter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub request_body: Option<OpenApiRequestBody>,
pub responses: OpenApiResponses,
}
impl OpenApiDocument {
pub fn to_json_pretty(&self) -> serde_json::Result<String> {
serde_json::to_string_pretty(self)
}
pub fn to_json(&self) -> serde_json::Result<String> {
serde_json::to_string(self)
}
}