-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Working conversion with still a few TODO
- Loading branch information
Showing
6 changed files
with
837 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
openapi-converter/clients_schema_to_openapi/src/components.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use openapiv3::{Components, Parameter, ReferenceOr, RequestBody, Response, Schema, StatusCode}; | ||
use clients_schema::{TypeDefinition, TypeName, TypeRegistry}; | ||
use crate::schemas::SchemaName; | ||
|
||
pub struct TypesAndComponents<'a> { | ||
pub types: TypeRegistry<'a>, | ||
pub components: &'a mut Components, | ||
} | ||
|
||
impl <'a> TypesAndComponents<'a> { | ||
pub fn new(types_vec: &'a Vec<TypeDefinition>, components: &'a mut Components) -> TypesAndComponents<'a> { | ||
TypesAndComponents { | ||
types: TypeRegistry::new(types_vec), | ||
components, | ||
} | ||
} | ||
|
||
pub fn add_request_body(&mut self, endpoint: &str, body: RequestBody,) -> ReferenceOr<RequestBody> { | ||
self.components.request_bodies.insert(endpoint.to_string(), ReferenceOr::Item(body)); | ||
ReferenceOr::Reference { | ||
reference: format!("#/components/requestBodies/{}", endpoint) | ||
} | ||
} | ||
|
||
pub fn add_parameter(&mut self, endpoint: &str, param: Parameter) -> ReferenceOr<Parameter> { | ||
let result = ReferenceOr::Reference { | ||
reference: format!("#/components/parameters/{}#{}", endpoint, ¶m.parameter_data_ref().name) | ||
}; | ||
self.components.parameters.insert(format!("{}#{}", endpoint, ¶m.parameter_data_ref().name), ReferenceOr::Item(param)); | ||
result | ||
} | ||
|
||
pub fn add_response(&mut self, endpoint: &str, status: StatusCode, response: Response) -> ReferenceOr<Response> { | ||
self.components.responses.insert(format!("{}#{}", endpoint, status), ReferenceOr::Item(response)); | ||
ReferenceOr::Reference { | ||
reference: format!("#/components/responses/{}#{}", endpoint, status) | ||
} | ||
} | ||
|
||
pub fn add_schema(&mut self, name: &TypeName, schema: ReferenceOr<Schema>) -> ReferenceOr<Schema> { | ||
self.components.schemas.insert(name.schema_name(), schema); | ||
name.schema_ref() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,91 @@ | ||
mod paths; | ||
mod schemas; | ||
mod components; | ||
|
||
use std::io::Write; | ||
use std::path::Path; | ||
use openapiv3::{Components, OpenAPI}; | ||
|
||
use clients_schema::{Model, Property, TypeDefinition, TypeName, TypeRegistry, ValueOf}; | ||
use clients_schema::{Endpoint, Model}; | ||
use crate::components::TypesAndComponents; | ||
|
||
pub fn convert_schema(path: impl AsRef<Path>, out: impl Write) -> anyhow::Result<()> { | ||
pub fn convert_schema_file(path: impl AsRef<Path>, endpoint_filter: fn(e: &Endpoint) -> bool, out: impl Write) -> anyhow::Result<()> { | ||
let file = std::fs::File::open(path)?; | ||
|
||
let model: Model = serde_json::from_reader(file)?; | ||
let types = model.type_registry(); | ||
|
||
let mut openapi = openapiv3::OpenAPI::default(); | ||
|
||
openapi.openapi = "3.1.0".into(); | ||
let openapi = convert_schema(&model, endpoint_filter)?; | ||
|
||
openapi.info = openapiv3::Info { | ||
title: "Elasticsearch API".to_string(), | ||
description: None, | ||
terms_of_service: None, | ||
contact: None, | ||
license: license(&model), | ||
version: "".to_string(), | ||
extensions: Default::default(), | ||
}; | ||
serde_json::to_writer_pretty(out, &openapi)?; | ||
Ok(()) | ||
} | ||
|
||
// Endpoints | ||
let paths = paths::build_paths(&model.endpoints, &types)?; | ||
pub fn convert_schema(model: &Model, endpoint_filter: fn(e: &Endpoint) -> bool) -> anyhow::Result<OpenAPI> { | ||
|
||
openapi.paths = openapiv3::Paths { | ||
paths: paths, | ||
let mut openapi = OpenAPI { | ||
openapi: "3.0.3".into(), | ||
info: info(model), | ||
servers: vec![], | ||
paths: Default::default(), | ||
components: Some(Components { | ||
security_schemes: Default::default(), | ||
// Filled from endpoints | ||
responses: Default::default(), | ||
// Filled from endpoints | ||
// TODO: add common request parameters and common cat parameters? | ||
parameters: Default::default(), | ||
examples: Default::default(), | ||
// Filled from endpoints | ||
request_bodies: Default::default(), | ||
headers: Default::default(), | ||
// Filled with type definitions | ||
schemas: Default::default(), | ||
links: Default::default(), | ||
callbacks: Default::default(), | ||
extensions: Default::default(), | ||
}), | ||
security: None, | ||
tags: vec![], | ||
external_docs: None, | ||
extensions: Default::default(), | ||
}; | ||
|
||
// Types | ||
let components = openapiv3::Components { | ||
security_schemes: Default::default(), | ||
responses: Default::default(), | ||
parameters: Default::default(), | ||
examples: Default::default(), | ||
request_bodies: Default::default(), | ||
headers: Default::default(), | ||
schemas: Default::default(), | ||
links: Default::default(), | ||
callbacks: Default::default(), | ||
extensions: Default::default(), | ||
}; | ||
let mut tac = TypesAndComponents::new(&model.types, openapi.components.as_mut().unwrap()); | ||
|
||
openapi.components = Some(components); | ||
// Endpoints | ||
for endpoint in model.endpoints.iter().filter(|e| endpoint_filter(e)) { | ||
paths::add_endpoint(endpoint, &mut tac, &mut openapi.paths)?; | ||
} | ||
//let paths = paths::build_paths(model.endpoints, &types)?; | ||
|
||
serde_json::to_writer_pretty(out, &openapi)?; | ||
Ok(()) | ||
//openapi.paths = openapiv3::Paths { | ||
// paths: paths, | ||
// extensions: Default::default(), | ||
//}; | ||
|
||
Ok(openapi) | ||
} | ||
|
||
fn license(model: &Model) -> Option<openapiv3::License> { | ||
if let Some(info) = &model.info { | ||
Some(openapiv3::License { | ||
name: info.license.name.clone(), | ||
url: Some(info.license.url.clone()), | ||
extensions: Default::default(), | ||
}) | ||
fn info(model: &Model) -> openapiv3::Info { | ||
let (title, license) = if let Some(info) = &model.info { | ||
( | ||
info.title.clone(), | ||
Some(openapiv3::License { | ||
name: info.license.name.clone(), | ||
url: Some(info.license.url.clone()), | ||
extensions: Default::default(), | ||
}) | ||
) | ||
} else { | ||
None | ||
("".to_string(), None) | ||
}; | ||
|
||
openapiv3::Info { | ||
title, | ||
description: None, | ||
terms_of_service: None, | ||
contact: None, | ||
license, | ||
version: "".to_string(), // TODO | ||
extensions: Default::default(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,18 @@ | ||
fn main() { | ||
clients_schema_to_openapi::convert_schema( | ||
"../../elasticsearch-specification/output/schema/schema.json", | ||
use tracing::Level; | ||
use tracing_subscriber::FmtSubscriber; | ||
|
||
fn main() -> anyhow::Result<()> { | ||
|
||
let subscriber = FmtSubscriber::builder() | ||
.with_max_level(Level::TRACE) | ||
.finish(); | ||
tracing::subscriber::set_global_default(subscriber)?; | ||
|
||
clients_schema_to_openapi::convert_schema_file( | ||
"../output/schema/schema-no-generics.json", | ||
|e| e.name == "search", | ||
std::io::stdout() | ||
).unwrap(); | ||
)?; | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.