use crate::{error::Error, response::Builder};
#[cfg(feature = "cookie")]
use cookie::{Cookie, CookieJar};
use hyper::body::Bytes;
use hyper::StatusCode;
use serde::Deserialize;
use std::{
borrow::{Borrow, BorrowMut},
ops::{Deref, DerefMut},
};
macro_rules! status_responder {
( $( $x:ty ),+ ) => {
$(
impl Responder for $x {
#[inline]
fn response(self, builder: Builder) -> Builder {
builder.status(self as u16)
}
}
)+
}
}
macro_rules! body_responder {
( $( $x:ty ),+ ) => {
$(
impl Responder for $x {
#[inline]
fn response(self, mut builder: Builder) -> Builder {
builder.body = self.into();
builder
}
}
)+
}
}
macro_rules! plain_body_responder {
( $( $x:ty ),+ ) => {
$(
impl Responder for $x {
#[inline]
fn response(self, builder: Builder) -> Builder {
builder.with("text/plain; charset=utf-8", self)
}
}
)+
}
}
macro_rules! tuple_responder {
( $($idx:tt -> $T:ident),+ ) => {
impl<$($T:Responder),+> Responder for ($($T),+) {
#[inline]
fn response(self, builder: Builder) -> Builder {
$(let builder = self.$idx.response(builder);)+
builder
}
}
}
}
status_responder!(u16, i16, u32, i32, u64, i64, usize, isize);
plain_body_responder!(String, &'static str);
body_responder!(Vec<u8>, &'static [u8], hyper::body::Bytes);
tuple_responder!(0->A, 1->B);
tuple_responder!(0->A, 1->B, 2->C);
tuple_responder!(0->A, 1->B, 2->C, 3->D);
tuple_responder!(0->A, 1->B, 2->C, 3->D, 4->E);
tuple_responder!(0->A, 1->B, 2->C, 3->D, 4->E, 5->F);
pub trait Responder {
fn response(self, builder: Builder) -> Builder;
}
impl<T> Responder for Vec<T>
where
T: Responder,
{
#[inline]
fn response(self, mut builder: Builder) -> Builder {
for responder in self {
builder = responder.response(builder);
}
builder
}
}
impl<T> Responder for &'static [T]
where
T: Responder + Clone,
{
#[inline]
fn response(self, mut builder: Builder) -> Builder {
for responder in self {
builder = responder.clone().response(builder);
}
builder
}
}
impl Responder for StatusCode {
#[inline]
fn response(self, builder: Builder) -> Builder {
builder.status(self)
}
}
impl Responder for () {
#[inline]
fn response(self, builder: Builder) -> Builder {
builder.status(200)
}
}
impl<T: Responder> Responder for Option<T> {
#[inline]
fn response(self, builder: Builder) -> Builder {
if let Some(r) = self {
r.response(builder).status_if_not_set(200)
} else {
builder.status_if_not_set(404)
}
}
}
impl<T: Responder, E: Responder> Responder for Result<T, E> {
#[inline]
fn response(self, builder: Builder) -> Builder {
match self {
Ok(r) => r.response(builder).status_if_not_set(200),
Err(r) => r.response(builder).status_if_not_set(500),
}
}
}
impl Responder for hyper::Error {
#[inline]
fn response(self, builder: Builder) -> Builder {
builder.status(500)
}
}
impl Responder for Builder {
#[inline]
fn response(self, _builder: Builder) -> Builder {
self
}
}
impl<T: serde::Serialize> Responder for Json<T> {
#[inline]
fn response(self, builder: Builder) -> Builder {
builder.json(&self.0)
}
}
impl<T: serde::Serialize> Responder for Form<T> {
#[inline]
fn response(self, builder: Builder) -> Builder {
builder.form(&self.0)
}
}
impl<T: Into<Bytes>> Responder for Html<T> {
fn response(self, builder: Builder) -> Builder {
builder.html(self.0)
}
}
#[cfg(feature = "cookie")]
impl Responder for Cookie<'static> {
#[inline]
fn response(self, builder: Builder) -> Builder {
builder.cookie(self)
}
}
#[cfg(feature = "cookie")]
impl Responder for CookieJar {
#[inline]
fn response(self, mut builder: Builder) -> Builder {
for c in self.iter() {
builder.inner.headers_mut().map(|h| {
h.append(
hyper::http::header::SET_COOKIE,
hyper::http::HeaderValue::from_str(c.to_string().as_str())
.expect("Invalid Cookie"),
)
});
}
builder
}
}
pub trait FromBytes {
type Output;
fn from_bytes(bytes: Bytes) -> Result<Self::Output, Error>
where
Self: Sized;
}
impl FromBytes for String {
type Output = String;
#[inline]
fn from_bytes(bytes: Bytes) -> Result<Self::Output, Error>
where
Self: Sized,
{
String::from_utf8(bytes.to_vec())
.map_err(|e| Error::Boxed(Box::new(e)))
.map(|s| s)
}
}
impl FromBytes for Vec<u8> {
type Output = Vec<u8>;
#[inline]
fn from_bytes(bytes: Bytes) -> Result<Self::Output, Error>
where
Self: Sized,
{
Ok(bytes.to_vec())
}
}
#[derive(Deserialize)]
pub struct Query<T>(pub T);
impl<T> Deref for Query<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Query<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> AsRef<T> for Query<T> {
fn as_ref(&self) -> &T {
&self.0
}
}
impl<T> AsMut<T> for Query<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> Borrow<T> for Query<T> {
fn borrow(&self) -> &T {
&self.0
}
}
impl<T> BorrowMut<T> for Query<T> {
fn borrow_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> FromBytes for Query<T>
where
T: for<'a> Deserialize<'a>,
{
type Output = T;
#[inline]
fn from_bytes(bytes: Bytes) -> Result<Self::Output, Error>
where
Self: Sized,
{
serde_urlencoded::from_bytes::<T>(&bytes.to_vec()).map_err(Error::SerdeUrlDe)
}
}
#[derive(Deserialize)]
pub struct Json<T>(pub T);
impl<T> Deref for Json<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Json<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> AsRef<T> for Json<T> {
fn as_ref(&self) -> &T {
&self.0
}
}
impl<T> AsMut<T> for Json<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> Borrow<T> for Json<T> {
fn borrow(&self) -> &T {
&self.0
}
}
impl<T> BorrowMut<T> for Json<T> {
fn borrow_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> FromBytes for Json<T>
where
T: for<'a> Deserialize<'a>,
{
type Output = T;
#[inline]
fn from_bytes(bytes: Bytes) -> Result<Self::Output, Error>
where
Self: Sized,
{
Ok(serde_json::from_slice(bytes.as_ref())?)
}
}
#[derive(Deserialize)]
pub struct Form<T>(pub T);
impl<T> Deref for Form<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Form<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> AsRef<T> for Form<T> {
fn as_ref(&self) -> &T {
&self.0
}
}
impl<T> AsMut<T> for Form<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> Borrow<T> for Form<T> {
fn borrow(&self) -> &T {
&self.0
}
}
impl<T> BorrowMut<T> for Form<T> {
fn borrow_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> FromBytes for Form<T>
where
T: for<'a> Deserialize<'a>,
{
type Output = T;
#[inline]
fn from_bytes(bytes: Bytes) -> Result<Self::Output, Error>
where
Self: Sized,
{
Ok(serde_urlencoded::from_bytes(bytes.as_ref())?)
}
}
pub struct Html<T>(pub T);
impl<T> Deref for Html<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Html<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> AsRef<T> for Html<T> {
fn as_ref(&self) -> &T {
&self.0
}
}
impl<T> AsMut<T> for Html<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> Borrow<T> for Html<T> {
fn borrow(&self) -> &T {
&self.0
}
}
impl<T> BorrowMut<T> for Html<T> {
fn borrow_mut(&mut self) -> &mut T {
&mut self.0
}
}