1mod parser;
2
3pub use parser::Metric;
4
5#[derive(Debug, thiserror::Error)]
6pub enum Error<'a> {
7 #[error("parse error: {0}")]
8 ParseError(nom::Err<nom::error::Error<&'a str>>),
9 #[error("unexpected input: {0}")]
10 UnexpectedInput(&'a str),
11}
12
13impl<'a> From<nom::Err<nom::error::Error<&'a str>>> for Error<'a> {
14 fn from(e: nom::Err<nom::error::Error<&'a str>>) -> Self {
15 Error::ParseError(e)
16 }
17}
18
19pub fn parse_server_timing(input: &str) -> Result<Vec<Metric>, Error> {
20 let (input, metrics) = parser::server_timing(input)?;
21
22 if input.is_empty() {
23 Ok(metrics)
24 } else {
25 Err(Error::UnexpectedInput(input))
26 }
27}
28
29#[cfg(test)]
30mod test {
31 use super::{parse_server_timing, Error};
32
33 #[test]
34 fn test_parse_server_timing() {
35 let input = "foo;dur=12.3;desc=bar";
36 let metrics = parse_server_timing(input).unwrap();
37 assert_eq!(
38 metrics,
39 vec![("foo", vec![("dur", "12.3".into()), ("desc", "bar".into())])],
40 );
41 }
42
43 #[test]
44 fn test_parse_server_timing_error() {
45 let input = "foo extra input";
46 let result = parse_server_timing(input);
47 assert!(result.is_err());
48 assert!(matches!(
49 result,
50 Err(Error::UnexpectedInput(" extra input"))
51 ));
52 }
53}