compiler-rs/clients_schema_to_openapi/src/utils.rs (98 lines of code) (raw):
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use clients_schema::TypeName;
use openapiv3::{ObjectType, ReferenceOr, Schema, SchemaData, SchemaKind, StringType, Type};
use crate::components::TypesAndComponents;
/// Extensions to `ReferenceOr` to ease conversion to boxed versions.
pub trait ReferenceOrBoxed<T> {
fn boxed(self) -> ReferenceOr<Box<T>>;
}
impl<T> ReferenceOrBoxed<T> for ReferenceOr<T> {
fn boxed(self) -> ReferenceOr<Box<T>> {
match self {
ReferenceOr::Item(t) => ReferenceOr::Item(Box::new(t)),
ReferenceOr::Reference { reference } => ReferenceOr::Reference { reference },
}
}
}
/// Extension to `TypeName` to return its name as an OpenAPI schema
pub trait SchemaName {
/// Name in the `#/components/schema` section
fn schema_name(&self) -> String;
/// Full reference
fn schema_ref(&self) -> ReferenceOr<Schema>;
}
impl SchemaName for TypeName {
// Use '.' as the separator: names and paths must be RFC 3986 compliant,
// and ':' output by `TypeName.toString()` is a reserved character.
fn schema_name(&self) -> String {
format!("{}.{}", self.namespace, self.name)
}
fn schema_ref(&self) -> ReferenceOr<Schema> {
ReferenceOr::Reference {
reference: format!("#/components/schemas/{}.{}", self.namespace, self.name),
}
}
}
/// Convenience extensions to turn OpenAPI type declarations into a `ReferenceOr<Schema>`.
/// This avoids a lot of boiler plate when creating schema objects.
pub trait IntoSchema {
fn into_schema_ref(self) -> ReferenceOr<Schema>
where Self: Sized {
ReferenceOr::Item(self.into_schema())
}
// fn into_schema_ref_with_base(self, base: &clients_schema::BaseType) -> ReferenceOr<Schema> where Self: Sized {
// let mut result = self.into_schema_ref();
// if let ReferenceOr::Item(ref mut schema) = &mut result {
// crate::schemas::fill_data_with_base(&mut schema.schema_data, base);
// }
// result
// }
fn into_schema_ref_with_data_fn(self, f: fn(&mut SchemaData) -> ()) -> ReferenceOr<Schema>
where Self: Sized {
let mut result = self.into_schema_ref();
if let ReferenceOr::Item(ref mut schema) = &mut result {
f(&mut schema.schema_data);
}
result
}
fn into_schema_with_base(self, tac: &TypesAndComponents, base: &clients_schema::BaseType) -> Schema
where Self: Sized {
let mut schema = self.into_schema();
tac.fill_data_with_base(&mut schema.schema_data, base);
schema
}
fn into_schema(self) -> Schema;
}
impl IntoSchema for Schema {
fn into_schema(self) -> Schema {
self
}
}
impl IntoSchema for ReferenceOr<Schema> {
fn into_schema_ref(self) -> ReferenceOr<Schema>
where Self: Sized {
self
}
fn into_schema(self) -> Schema {
match self {
ReferenceOr::Item(schema) => schema,
ReferenceOr::Reference { .. } => SchemaKind::AllOf { all_of: vec![self] }.into_schema(),
}
}
}
impl IntoSchema for SchemaKind {
fn into_schema(self) -> Schema {
Schema {
schema_data: Default::default(),
schema_kind: self,
}
}
}
impl IntoSchema for Type {
fn into_schema(self) -> Schema {
Schema {
schema_kind: SchemaKind::Type(self),
schema_data: Default::default(),
}
}
}
impl IntoSchema for ObjectType {
fn into_schema(self) -> Schema {
Schema {
schema_kind: SchemaKind::Type(Type::Object(self)),
schema_data: Default::default(),
}
}
}
impl IntoSchema for StringType {
fn into_schema(self) -> Schema {
Schema {
schema_kind: SchemaKind::Type(Type::String(self)),
schema_data: Default::default(),
}
}
}