ippper 0.6.0

A library for building simple ipp servers
Documentation
use crate::body::Body;
use crate::body_reader::BodyReader;
use crate::service::IppService;
use anyhow;
use bytes::Buf;
use http::{Method, Request, Response, StatusCode};
use http_body::Body as HttpBody;
use ipp::parser::AsyncIppParser;

pub async fn handle_ipp_via_http<ReqBody, ReqData, ReqError>(
    req: Request<ReqBody>,
    handler: &impl IppService,
) -> Result<Response<Body>, anyhow::Error>
where
    ReqData: Buf + Send + Sync + Unpin + 'static,
    ReqError: std::error::Error + Send + Sync + 'static,
    ReqBody: HttpBody<Data = ReqData, Error = ReqError> + Send + Sync + Unpin + 'static,
{
    if req.method() != Method::POST {
        return Ok(Response::builder()
            .status(StatusCode::METHOD_NOT_ALLOWED)
            .header("Allow", "POST")
            .body(Body::from("405 Method Not Allowed"))
            .unwrap());
    }
    if req.headers().get("Content-Type") != Some(&"application/ipp".parse().unwrap()) {
        return Ok(Response::builder()
            .status(StatusCode::UNSUPPORTED_MEDIA_TYPE)
            .body(Body::from("415 Unsupported Media Type"))
            .unwrap());
    }
    let (head, body) = req.into_parts();
    let reader = BodyReader::new(body);
    let ipp_request = AsyncIppParser::new(reader).parse().await?;
    let response = handler.handle_request(head, ipp_request).await;
    let body = Body::from(response);
    Ok(Response::builder()
        .status(200)
        .header("Content-Type", "application/ipp")
        .body(body)
        .unwrap())
}