puzz 0.2.0

A simple and powerful web framework.
Documentation
use std::fmt;
use std::str::FromStr;

use puzz_core::http::HeaderName;
use puzz_core::{BoxError, Request};

pub fn header<T>(request: &Request, name: HeaderName) -> Result<T, ExtractHeaderError>
where
    T: FromStr,
    T::Err: Into<BoxError>,
{
    if let Some(value) = request.headers().get(&name) {
        match value.to_str() {
            Ok(s) => s
                .parse::<T>()
                .map_err(|e| ExtractHeaderError::InvalidHeader {
                    name,
                    source: e.into(),
                }),
            Err(e) => Err(ExtractHeaderError::InvalidHeader {
                name,
                source: e.into(),
            }),
        }
    } else {
        Err(ExtractHeaderError::MissingHeader { name })
    }
}

#[derive(Debug)]
pub enum ExtractHeaderError {
    MissingHeader { name: HeaderName },
    InvalidHeader { name: HeaderName, source: BoxError },
}

impl fmt::Display for ExtractHeaderError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ExtractHeaderError::MissingHeader { name } => {
                write!(f, "missing request header `{}`", name)
            }
            ExtractHeaderError::InvalidHeader { name, source: _ } => {
                write!(f, "invalid request header `{}`", name)
            }
        }
    }
}

impl std::error::Error for ExtractHeaderError {}