server-timing 0.1.0

A parser for the server-timing header
Documentation
mod parser;

pub use parser::Metric;

#[derive(Debug, thiserror::Error)]
pub enum Error<'a> {
    #[error("parse error: {0}")]
    ParseError(nom::Err<nom::error::Error<&'a str>>),
    #[error("unexpected input: {0}")]
    UnexpectedInput(&'a str),
}

impl<'a> From<nom::Err<nom::error::Error<&'a str>>> for Error<'a> {
    fn from(e: nom::Err<nom::error::Error<&'a str>>) -> Self {
        Error::ParseError(e)
    }
}

pub fn parse_server_timing(input: &str) -> Result<Vec<Metric>, Error> {
    let (input, metrics) = parser::server_timing(input)?;

    if input.is_empty() {
        Ok(metrics)
    } else {
        Err(Error::UnexpectedInput(input))
    }
}

#[cfg(test)]
mod test {
    use super::{parse_server_timing, Error};

    #[test]
    fn test_parse_server_timing() {
        let input = "foo;dur=12.3;desc=bar";
        let metrics = parse_server_timing(input).unwrap();
        assert_eq!(
            metrics,
            vec![("foo", vec![("dur", "12.3".into()), ("desc", "bar".into())])],
        );
    }

    #[test]
    fn test_parse_server_timing_error() {
        let input = "foo extra input";
        let result = parse_server_timing(input);
        assert!(result.is_err());
        assert!(matches!(
            result,
            Err(Error::UnexpectedInput(" extra input"))
        ));
    }
}