#![allow(clippy::expect_used)]
#![allow(clippy::print_stdout)]
#![allow(dead_code)]
use std::sync::Arc;
use serde::{Deserialize, Serialize};
use tower_conneg::{ErasedFormat, JsonFormat, MsgPackNamedFormat, ServerConfig};
use utoipa::openapi::{
HttpMethod, OpenApi as OpenApiDocument, PathItem, PathsBuilder, path::OperationBuilder,
};
use utoipa::{OpenApi, ToSchema};
#[derive(OpenApi)]
#[openapi(components(schemas(CreateUserRequest, User, ApiError)))]
struct ApiDoc;
#[derive(Debug, Deserialize, ToSchema)]
struct CreateUserRequest {
name: String,
email: String,
}
#[derive(Debug, Serialize, ToSchema)]
struct User {
id: u64,
name: String,
email: String,
}
#[derive(Debug, Serialize, ToSchema)]
struct ApiError {
code: String,
message: String,
}
fn config() -> ServerConfig {
let json: Arc<dyn ErasedFormat> = Arc::new(JsonFormat);
let msgpack: Arc<dyn ErasedFormat> = Arc::new(MsgPackNamedFormat);
ServerConfig::builder()
.formats([json.clone(), msgpack])
.fallback_format(json)
.build()
}
fn create_user_operation(config: &ServerConfig) -> PathItem {
let docs = config.openapi_formats();
let operation = OperationBuilder::new()
.operation_id(Some("create_user"))
.request_body(Some(docs.required_request_body::<CreateUserRequest>()))
.response("201", docs.response::<User, _>("Created user."))
.response("406", docs.not_acceptable_response_with_body::<ApiError>())
.response(
"415",
docs.unsupported_media_type_post_response_with_body::<ApiError>(),
)
.build();
PathItem::new(HttpMethod::Post, operation)
}
fn openapi(config: &ServerConfig) -> OpenApiDocument {
let mut api = ApiDoc::openapi();
api.paths = PathsBuilder::new()
.path("/users", create_user_operation(config))
.build();
api
}
fn main() {
println!(
"{}",
serde_json::to_string_pretty(&openapi(&config())).expect("OpenAPI should serialize")
);
}