// Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use axum::http::{header, HeaderValue, StatusCode}; use axum::response::{IntoResponse, Response}; use axum::Json; use bytes::{BufMut, BytesMut}; use serde::{Deserialize, Serialize}; pub mod middleware; #[derive(Debug, Clone)] pub enum FormattedResponse { Json(Json), Yaml(Yaml), } impl IntoResponse for FormattedResponse where T: Serialize, { fn into_response(self) -> Response { match self { FormattedResponse::Json(json_response) => json_response.into_response(), FormattedResponse::Yaml(yaml_response) => yaml_response.into_response(), } } } #[derive(Default, Debug, Serialize, Deserialize, Copy, Clone)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "lowercase")] pub enum Output { #[default] Json, Yaml, } #[derive(Default, Debug, Serialize, Deserialize, Copy, Clone)] #[cfg_attr(feature = "utoipa", derive(utoipa::IntoParams, utoipa::ToSchema))] #[serde(default)] pub struct OutputParams { pub output: Option, } impl Output { pub fn to_response(self, data: T) -> FormattedResponse { match self { Output::Json => FormattedResponse::Json(Json(data)), Output::Yaml => FormattedResponse::Yaml(Yaml(data)), } } } #[derive(Debug, Clone, Copy, Default)] #[must_use] pub struct Yaml(pub T); impl From for Yaml { fn from(inner: T) -> Self { Self(inner) } } impl IntoResponse for Yaml where T: Serialize, { // replicates axum's Json fn into_response(self) -> Response { let mut buf = BytesMut::with_capacity(128).writer(); match serde_yaml::to_writer(&mut buf, &self.0) { Ok(()) => ( [( header::CONTENT_TYPE, HeaderValue::from_static("application/yaml"), )], buf.into_inner().freeze(), ) .into_response(), Err(err) => ( StatusCode::INTERNAL_SERVER_ERROR, [( header::CONTENT_TYPE, HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()), )], err.to_string(), ) .into_response(), } } }