use axum::routing::MethodRouter;
use std::fmt;
use super::super::extractor::ExtractorKind;
use super::RouteConfig;
use super::openapi_converter::OpenApiConverter;
use openapiv3 as oa;
use openapiv3::Operation;
#[derive(Clone, Debug)]
pub enum Method {
Get,
Post,
Put,
Patch,
Delete,
Head,
Options,
Trace,
Connect,
}
impl fmt::Display for Method {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Method::Get => "GET",
Method::Post => "POST",
Method::Put => "PUT",
Method::Patch => "PATCH",
Method::Delete => "DELETE",
Method::Options => "OPTIONS",
Method::Head => "HEAD",
Method::Trace => "TRACE",
Method::Connect => "CONNECT"
};
write!(f, "{s}")
}
}
#[derive(Clone, Debug)]
pub struct Route<S = ()> {
pub method: Method,
pub path: String,
pub handler: MethodRouter<S>,
pub operation: oa::Operation,
}
impl<S> Route<S> {
pub fn new(method: Method, path: String, handler: MethodRouter<S>) -> Self {
Self {
method,
path,
handler,
operation: Operation::default(),
}
}
pub fn set_openapi_operation(&mut self, extractor_kinds: Vec<ExtractorKind>) -> &mut Self {
let mut converter = OpenApiConverter::new();
for kind in extractor_kinds {
converter.process_extractor_kind(kind);
}
self.operation = converter.into_operation();
self
}
pub fn set_route_config(&mut self, route_config: RouteConfig) -> &mut Self {
self.operation.summary = route_config.summary;
self.operation.description = route_config.description;
self.operation.tags = route_config.tags;
let mut responses = indexmap::IndexMap::new();
for (status, config) in route_config.responses {
let mut content = indexmap::IndexMap::new();
if let Some(js_schema) = config.schema {
let oa_schema = OpenApiConverter::convert_schemars_to_oa(&js_schema);
content.insert(
"application/json".to_string(),
oa::MediaType {
schema: Some(oa::ReferenceOr::Item(oa_schema)),
example: None,
examples: indexmap::IndexMap::new(),
encoding: indexmap::IndexMap::new(),
extensions: indexmap::IndexMap::new(),
},
);
}
let response = oa::Response {
description: config.description,
content,
headers: indexmap::IndexMap::new(),
links: indexmap::IndexMap::new(),
extensions: indexmap::IndexMap::new(),
};
responses.insert(oa::StatusCode::Code(status), oa::ReferenceOr::Item(response));
}
self.operation.responses = OpenApiConverter::build_responses(responses);
self
}
}