actix-msgpack 0.1.4

Msgpack payload extractor for Actix Web
Documentation
use crate::MsgPackExtractorFuture;

use super::{MsgPackConfig, MsgPackError, MsgPackMessage, DEFAULT_CONFIG};
use actix_web::{
	body::BoxBody, dev::Payload, error::Error, FromRequest, HttpRequest, HttpResponse, Responder,
};
use mime::APPLICATION_MSGPACK;
use serde::{de::DeserializeOwned, Serialize};
use std::{
	fmt,
	ops::{Deref, DerefMut},
};

pub struct MsgPack<T>(pub T);

impl<T> Deref for MsgPack<T> {
	type Target = T;

	fn deref(&self) -> &T {
		&self.0
	}
}

impl<T> DerefMut for MsgPack<T> {
	fn deref_mut(&mut self) -> &mut T {
		&mut self.0
	}
}

impl<T> fmt::Debug for MsgPack<T>
where
	T: fmt::Debug,
{
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		write!(f, "MsgPack: {:?}", self.0)
	}
}

impl<T> fmt::Display for MsgPack<T>
where
	T: fmt::Display,
{
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		fmt::Display::fmt(&self.0, f)
	}
}

impl<T: DeserializeOwned> FromRequest for MsgPack<T>
where
	T: 'static,
{
	type Error = Error;
	type Future = MsgPackExtractorFuture<T>;

	#[inline]
	fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
		let config = req.app_data::<MsgPackConfig>().unwrap_or(&DEFAULT_CONFIG);
		let limit = config.limit;
		let err_handler = config.error_handler.clone();
		let content_type = config.content_type.clone();

		MsgPackExtractorFuture {
			req: req.clone(),
			fut: MsgPackMessage::new(req, payload, content_type).limit(limit),
			err_handler,
		}
	}
}

impl<T: Serialize> Responder for MsgPack<T> {
	type Body = BoxBody;

	fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
		match rmp_serde::to_vec_named(&self.0) {
			Ok(body) => {
				match HttpResponse::Ok().content_type(APPLICATION_MSGPACK).message_body(body) {
					Ok(response) => response.map_into_boxed_body(),
					Err(err) => HttpResponse::from_error(err),
				}
			},
			Err(err) => HttpResponse::from_error(MsgPackError::Serialize(err)),
		}
	}
}