#![allow(clippy::derive_partial_eq_without_eq)]
use crate::models::components::Components;
use crate::models::info::Info;
use crate::models::paths::{ExternalDocumentation, Paths};
use crate::models::security::SecurityRequirement;
use crate::models::server::Server;
use crate::models::tag::Tag;
use indexmap::IndexMap;
use serde::Serialize;
use serde_json::Value;
pub mod components;
pub mod info;
pub mod paths;
pub mod reference_or;
pub mod security;
pub mod server;
pub mod tag;
pub use schemars::schema::*;
#[derive(Serialize, Clone, Debug)]
#[cfg_attr(
any(test, feature = "deserialize"),
derive(serde::Deserialize, PartialEq)
)]
pub enum OpenApiVersion {
#[serde(rename = "3.0.3")]
OAS3_0,
}
impl Default for OpenApiVersion {
fn default() -> Self {
Self::OAS3_0
}
}
#[derive(Serialize, Clone, Debug, Default)]
#[cfg_attr(
any(test, feature = "deserialize"),
derive(serde::Deserialize, PartialEq)
)]
#[serde(rename_all = "camelCase")]
pub struct OpenApi {
pub openapi: OpenApiVersion,
pub info: Info,
pub servers: Vec<Server>,
pub paths: Paths,
#[serde(skip_serializing_if = "Option::is_none")]
pub components: Option<Components>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub security: Vec<SecurityRequirement>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub tags: Vec<Tag>,
#[serde(skip_serializing_if = "Option::is_none")]
pub external_docs: Option<ExternalDocumentation>,
#[serde(
flatten,
skip_serializing_if = "IndexMap::is_empty",
skip_deserializing
)]
pub extensions: IndexMap<String, Value>,
}
#[cfg(test)]
mod test {
#![allow(clippy::expect_used)]
use crate::models::info::Info;
use crate::models::paths::{Operation, OperationType, PathItem, Paths, Response, Responses};
use crate::models::reference_or::ReferenceOr;
use crate::models::server::Server;
use crate::models::tag::Tag;
use crate::models::{OpenApi, OpenApiVersion};
use indexmap::IndexMap;
use std::collections::BTreeMap;
#[test]
fn empty_openapi_properly_generated() {
let oas = OpenApi {
openapi: OpenApiVersion::OAS3_0,
info: Info {
title: "Test".to_string(),
description: Some("Description".to_string()),
version: "1.0.0".to_string(),
..Default::default()
},
paths: Paths::default(),
..Default::default()
};
let oas_json = serde_json::to_string_pretty(&oas).expect("Error generating json for oas");
assert_eq!(
oas_json,
include_str!("../../test-assets/empty-openapi.json")
);
}
#[test]
fn openapi_properly_generated() {
let oas = OpenApi {
openapi: OpenApiVersion::OAS3_0,
info: Info {
title: "Test".to_string(),
description: Some("Description".to_string()),
version: "1.0.0".to_string(),
..Default::default()
},
servers: vec![Server {
url: "https://google.com".to_string(),
description: Some("A big search server".to_string()),
..Default::default()
}],
paths: Paths {
paths: IndexMap::from_iter(vec![(
"/search".to_string(),
PathItem {
operations: IndexMap::from_iter(vec![(
OperationType::Get,
Operation {
tags: vec!["Search".to_string()],
summary: Some("I don't know what this do".to_string()),
operation_id: Some("get_search".to_string()),
responses: Responses {
responses: BTreeMap::from_iter(vec![(
"200".to_string(),
ReferenceOr::Object(Response {
description: "A search thingy".to_string(),
..Default::default()
}),
)]),
..Default::default()
},
..Default::default()
},
)]),
..Default::default()
},
)]),
..Default::default()
},
tags: vec![Tag {
name: "Search".to_string(),
..Default::default()
}],
..Default::default()
};
let oas_json = serde_json::to_string_pretty(&oas).expect("Error generating json for oas");
assert_eq!(oas_json, include_str!("../../test-assets/openapi.json"));
}
}