use {crate::content_types::APPLICATION_PROTOBUF,
axum::{http::{StatusCode,
header::CONTENT_TYPE},
response::{IntoResponse,
Response}},
prost::Message};
pub struct ProtobufResponse<T>
where
T: Message, {
status: StatusCode,
message: T,
}
impl<T> ProtobufResponse<T>
where
T: Message,
{
pub fn new(status: StatusCode, message: T) -> Self {
Self { status, message }
}
pub fn ok(message: T) -> Self {
Self::new(StatusCode::OK, message)
}
pub fn created(message: T) -> Self {
Self::new(StatusCode::CREATED, message)
}
pub fn accepted(message: T) -> Self {
Self::new(StatusCode::ACCEPTED, message)
}
}
impl<T> IntoResponse for ProtobufResponse<T>
where
T: Message,
{
fn into_response(self) -> Response {
let bytes = self.message.encode_to_vec();
(self.status, [(CONTENT_TYPE, APPLICATION_PROTOBUF)], bytes).into_response()
}
}
pub type ProtobufResult<T> = Result<ProtobufResponse<T>, crate::error::JetError>;
pub struct NoContent;
impl IntoResponse for NoContent {
fn into_response(self) -> Response {
StatusCode::NO_CONTENT.into_response()
}
}
pub enum MaybeProtobuf<T>
where
T: Message, {
Some(ProtobufResponse<T>),
None,
}
impl<T> IntoResponse for MaybeProtobuf<T>
where
T: Message,
{
fn into_response(self) -> Response {
match self {
| MaybeProtobuf::Some(response) => response.into_response(),
| MaybeProtobuf::None => StatusCode::NO_CONTENT.into_response(),
}
}
}
pub trait IntoProtobufResponse: Message + Sized {
fn into_pb_response(self) -> ProtobufResponse<Self> {
ProtobufResponse::ok(self)
}
fn into_pb_response_with_status(self, status: StatusCode) -> ProtobufResponse<Self> {
ProtobufResponse::new(status, self)
}
}
impl<T: Message> IntoProtobufResponse for T {}