openapi_kit_renderer 0.0.15

OpenAPI Renderer
Documentation
use crate::schema::parameter::OpenAPIParameter;
use crate::schema::request::OpenAPIRequest;
use crate::schema::resolve_schema;
use crate::schema::response::OpenAPIResponse;
use indexmap::IndexMap;
use openapi_kit_schema::{ParameterSchemaOrContent, ReferenceOr, RequestBody};
use serde::Deserialize;
use serde::Serialize;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OpenAPIOperation {
    pub operation_id: Option<String>,
    pub parameters: Vec<OpenAPIParameter>,
    pub request: Option<OpenAPIRequest>,
    pub response: IndexMap<String, OpenAPIResponse>,
}

impl From<openapi_kit_schema::Operation> for OpenAPIOperation {
    fn from(value: openapi_kit_schema::Operation) -> Self {
        OpenAPIOperation {
            operation_id: value.operation_id,
            parameters: convert_parameters(value.parameters),
            request: value.request_body.and_then(convert_request),
            response: convert_response(value.responses),
        }
    }
}

fn convert_parameters(
    parameters: Vec<ReferenceOr<openapi_kit_schema::Parameter>>,
) -> Vec<OpenAPIParameter> {
    let mut output = Vec::new();

    for ref_or_parameter in parameters {
        match ref_or_parameter {
            ReferenceOr::Reference { reference: _ } => {
                continue;
            }
            ReferenceOr::Item(parameter) => {
                let location = match parameter {
                    openapi_kit_schema::Parameter::Header { .. } => "header",
                    openapi_kit_schema::Parameter::Cookie { .. } => "cookie",
                    openapi_kit_schema::Parameter::Path { .. } => "path",
                    openapi_kit_schema::Parameter::Query { .. } => "query",
                }
                .to_string();

                let data = parameter.parameter_data();

                output.push(OpenAPIParameter {
                    r#in: location,
                    kind: match data.format {
                        ParameterSchemaOrContent::Content(_) => {
                            continue;
                        }
                        ParameterSchemaOrContent::Schema(ref_or_schema) => {
                            resolve_schema(ref_or_schema)
                        }
                    },
                    name: data.name,
                });
            }
        }
    }

    output
}

fn convert_response(
    responses_object: openapi_kit_schema::Responses,
) -> IndexMap<String, OpenAPIResponse> {
    let mut responses = IndexMap::new();

    for (code, response) in responses_object.responses {
        if let ReferenceOr::Item(response) = response {
            for (media_type, media) in response.content {
                if let Some(ref_or_schema) = media.schema {
                    responses.insert(
                        code.to_string(),
                        OpenAPIResponse {
                            kind: resolve_schema(ref_or_schema),
                            media: media_type.to_string(),
                        },
                    );
                }
            }
        } else {
            println!("Currently no support for $ref in response.");
        }
    }

    responses
}

fn convert_request(ref_or_request: ReferenceOr<RequestBody>) -> Option<OpenAPIRequest> {
    if let ReferenceOr::Item(request) = ref_or_request {
        for (media_type, media) in request.content {
            if let Some(ref_or_schema) = media.schema {
                return Some(OpenAPIRequest {
                    kind: resolve_schema(ref_or_schema),
                    media: media_type.to_string(),
                });
            }
        }
    } else {
        println!("Currently no support for $ref in response.");
    }

    None
}