zon_core 0.0.4

part of a new WIP, very incomplete async http service stack
Documentation
use std::convert::Infallible;

use bytes::Bytes;
use http::StatusCode;

use super::{Response, ResponseParts};
use crate::{Body, BoxError};

pub trait IntoResponse {
    /// Turn `self` into an HTTP response.
    ///
    /// Both the `Ok` and `Err` variants contain a [`Response`], but it is
    /// important which variant is used: In the `Err` case, tuples of
    /// multiple [`ToResponseParts`] elements and one [`IntoResponse`] element
    /// at the end will discard the result of the first elements and only return
    /// the error response.
    fn into_response(self) -> Result<Response, Response>;
}

impl IntoResponse for () {
    #[inline]
    fn into_response(self) -> Result<Response, Response> {
        Ok(Response::new(Body::empty()))
    }
}

impl IntoResponse for Infallible {
    fn into_response(self) -> Result<Response, Response> {
        match self {}
    }
}

impl IntoResponse for StatusCode {
    #[inline]
    fn into_response(self) -> Result<Response, Response> {
        let mut res = Response::new(Body::empty());
        *res.status_mut() = self;
        Ok(res)
    }
}

impl IntoResponse for Body {
    #[inline]
    fn into_response(self) -> Result<Response, Response> {
        Ok(Response::new(self))
    }
}

impl IntoResponse for &str {
    #[inline]
    fn into_response(self) -> Result<Response, Response> {
        Body::from(self.to_owned()).into_response()
    }
}

impl IntoResponse for String {
    #[inline]
    fn into_response(self) -> Result<Response, Response> {
        Body::from(self).into_response()
    }
}

impl<B> IntoResponse for Response<B>
where
    B: http_body::Body<Data = Bytes, Error: Into<BoxError>> + Send + 'static,
{
    #[inline]
    fn into_response(self) -> Result<Response, Response> {
        Ok(self.map(Body::new))
    }
}

impl IntoResponse for ResponseParts {
    fn into_response(self) -> Result<Response, Response> {
        Ok(Response::from_parts(self, Body::empty()))
    }
}

impl<T, E> IntoResponse for Result<T, E>
where
    T: IntoResponse,
    E: IntoResponse,
{
    fn into_response(self) -> Result<Response, Response> {
        match self {
            // For Ok, just run the inner into_response
            Ok(value) => value.into_response(),
            // For Err, run the inner into_response but always return the
            // response it creates as an Err.
            Err(err) => {
                let (Ok(res) | Err(res)) = err.into_response();
                Err(res)
            }
        }
    }
}

impl<T> IntoResponse for (StatusCode, T)
where
    T: IntoResponse,
{
    fn into_response(self) -> Result<Response, Response> {
        let (status_code, res) = self;
        let mut res = res.into_response()?;
        *res.status_mut() = status_code;
        Ok(res)
    }
}