use crate::response::{ResponseWrapper, error_response};
use axum::http::header::IntoHeaderName;
use axum::http::{HeaderValue, header};
use axum::response::{IntoResponse, Response};
use bytes::{BufMut, BytesMut};
use serde::Serialize;
#[derive(Debug, Clone, Default)]
#[must_use]
pub struct Bincode<T>(pub(crate) ResponseWrapper<T>);
impl<T> From<T> for Bincode<T> {
fn from(response: T) -> Self {
Bincode(ResponseWrapper::new(response).with_header(
header::CONTENT_TYPE,
HeaderValue::from_static("application/bincode"),
))
}
}
impl<T> Bincode<T> {
pub(crate) fn with_header(
mut self,
name: impl IntoHeaderName,
value: impl Into<HeaderValue>,
) -> Self {
self.0.headers.insert(name, value.into());
self
}
pub(crate) fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Bincode<U> {
Bincode(self.0.map(op))
}
}
impl<T> IntoResponse for Bincode<T>
where
T: Serialize,
{
fn into_response(self) -> Response {
use bincode::Options;
let mut buf = BytesMut::with_capacity(128).writer();
match crate::make_bincode_serializer().serialize_into(&mut buf, &self.0.data) {
Ok(()) => (self.0.headers, buf.into_inner().freeze()).into_response(),
Err(err) => error_response(err),
}
}
}