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"))
));
}
}