mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-04-20 06:54:46 +00:00
merge workspace and main crate
This commit is contained in:
parent
52679ad29d
commit
5587ded60d
45 changed files with 58 additions and 67 deletions
162
src/openapi/builder.rs
Normal file
162
src/openapi/builder.rs
Normal file
|
@ -0,0 +1,162 @@
|
|||
use crate::{OpenapiType, OpenapiSchema};
|
||||
use indexmap::IndexMap;
|
||||
use openapiv3::{
|
||||
Components, OpenAPI, PathItem, ReferenceOr, ReferenceOr::Item, ReferenceOr::Reference, Schema,
|
||||
Server
|
||||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OpenapiInfo
|
||||
{
|
||||
pub title : String,
|
||||
pub version : String,
|
||||
pub urls : Vec<String>
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OpenapiBuilder
|
||||
{
|
||||
pub openapi : Arc<RwLock<OpenAPI>>
|
||||
}
|
||||
|
||||
impl OpenapiBuilder
|
||||
{
|
||||
pub fn new(info : OpenapiInfo) -> Self
|
||||
{
|
||||
Self {
|
||||
openapi: Arc::new(RwLock::new(OpenAPI {
|
||||
openapi: "3.0.2".to_string(),
|
||||
info: openapiv3::Info {
|
||||
title: info.title,
|
||||
version: info.version,
|
||||
..Default::default()
|
||||
},
|
||||
servers: info.urls.into_iter()
|
||||
.map(|url| Server { url, ..Default::default() })
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove path from the OpenAPI spec, or return an empty one if not included. This is handy if you need to
|
||||
/// modify the path and add it back after the modification
|
||||
pub fn remove_path(&mut self, path : &str) -> PathItem
|
||||
{
|
||||
let mut openapi = self.openapi.write().unwrap();
|
||||
match openapi.paths.swap_remove(path) {
|
||||
Some(Item(item)) => item,
|
||||
_ => PathItem::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_path<Path : ToString>(&mut self, path : Path, item : PathItem)
|
||||
{
|
||||
let mut openapi = self.openapi.write().unwrap();
|
||||
openapi.paths.insert(path.to_string(), Item(item));
|
||||
}
|
||||
|
||||
fn add_schema_impl(&mut self, name : String, mut schema : OpenapiSchema)
|
||||
{
|
||||
self.add_schema_dependencies(&mut schema.dependencies);
|
||||
|
||||
let mut openapi = self.openapi.write().unwrap();
|
||||
match &mut openapi.components {
|
||||
Some(comp) => {
|
||||
comp.schemas.insert(name, Item(schema.into_schema()));
|
||||
},
|
||||
None => {
|
||||
let mut comp = Components::default();
|
||||
comp.schemas.insert(name, Item(schema.into_schema()));
|
||||
openapi.components = Some(comp);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn add_schema_dependencies(&mut self, dependencies : &mut IndexMap<String, OpenapiSchema>)
|
||||
{
|
||||
let keys : Vec<String> = dependencies.keys().map(|k| k.to_string()).collect();
|
||||
for dep in keys
|
||||
{
|
||||
let dep_schema = dependencies.swap_remove(&dep);
|
||||
if let Some(dep_schema) = dep_schema
|
||||
{
|
||||
self.add_schema_impl(dep, dep_schema);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_schema<T : OpenapiType>(&mut self) -> ReferenceOr<Schema>
|
||||
{
|
||||
let mut schema = T::schema();
|
||||
match schema.name.clone() {
|
||||
Some(name) => {
|
||||
let reference = Reference { reference: format!("#/components/schemas/{}", name) };
|
||||
self.add_schema_impl(name, schema);
|
||||
reference
|
||||
},
|
||||
None => {
|
||||
self.add_schema_dependencies(&mut schema.dependencies);
|
||||
Item(schema.into_schema())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)]
|
||||
mod test
|
||||
{
|
||||
use super::*;
|
||||
|
||||
#[derive(OpenapiType)]
|
||||
struct Message
|
||||
{
|
||||
msg : String
|
||||
}
|
||||
|
||||
#[derive(OpenapiType)]
|
||||
struct Messages
|
||||
{
|
||||
msgs : Vec<Message>
|
||||
}
|
||||
|
||||
fn info() -> OpenapiInfo
|
||||
{
|
||||
OpenapiInfo {
|
||||
title: "TEST CASE".to_owned(),
|
||||
version: "1.2.3".to_owned(),
|
||||
urls: vec!["http://localhost:1234".to_owned(), "https://example.org".to_owned()]
|
||||
}
|
||||
}
|
||||
|
||||
fn openapi(builder : OpenapiBuilder) -> OpenAPI
|
||||
{
|
||||
Arc::try_unwrap(builder.openapi).unwrap().into_inner().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_builder()
|
||||
{
|
||||
let info = info();
|
||||
let builder = OpenapiBuilder::new(info.clone());
|
||||
let openapi = openapi(builder);
|
||||
|
||||
assert_eq!(info.title, openapi.info.title);
|
||||
assert_eq!(info.version, openapi.info.version);
|
||||
assert_eq!(info.urls.len(), openapi.servers.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_schema()
|
||||
{
|
||||
let mut builder = OpenapiBuilder::new(info());
|
||||
builder.add_schema::<Option<Messages>>();
|
||||
let openapi = openapi(builder);
|
||||
|
||||
assert_eq!(openapi.components.clone().unwrap_or_default().schemas["Message"] , ReferenceOr::Item(Message ::schema().into_schema()));
|
||||
assert_eq!(openapi.components.clone().unwrap_or_default().schemas["Messages"], ReferenceOr::Item(Messages::schema().into_schema()));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue