use std::convert::TryFrom;
use nom::{
bytes::complete::{tag, take_while_m_n},
combinator::{all_consuming, map_res},
error::ErrorKind,
sequence::{preceded, terminated, tuple},
};
use snafu::Snafu;
#[derive(Debug, Snafu, PartialEq, Eq)]
pub enum ParseError {
#[snafu(display("failed to parse NginxStubStatus, kind: `{:?}`", kind))]
NginxStubStatusParseError { kind: ErrorKind },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NginxStubStatus {
pub active: usize,
pub accepts: usize,
pub handled: usize,
pub requests: usize,
pub reading: usize,
pub writing: usize,
pub waiting: usize,
}
fn get_usize(input: &str) -> nom::IResult<&str, usize, nom::error::Error<&str>> {
map_res(
take_while_m_n(1, 20, |c: char| c.is_ascii_digit()),
|s: &str| s.parse::<usize>(),
)(input)
}
impl<'a> TryFrom<&'a str> for NginxStubStatus {
type Error = ParseError;
fn try_from(input: &'a str) -> Result<Self, Self::Error> {
match all_consuming(tuple((
preceded(tag("Active connections: "), get_usize),
preceded(tag(" \nserver accepts handled requests\n "), get_usize),
preceded(tag(" "), get_usize),
preceded(tag(" "), get_usize),
preceded(tag(" \nReading: "), get_usize),
preceded(tag(" Writing: "), get_usize),
terminated(preceded(tag(" Waiting: "), get_usize), tag(" \n")),
)))(input)
{
Ok((_, (active, accepts, handled, requests, reading, writing, waiting))) => {
Ok(NginxStubStatus {
active,
accepts,
handled,
requests,
reading,
writing,
waiting,
})
}
Err(error) => match error {
nom::Err::Error(error) => {
Err(ParseError::NginxStubStatusParseError { kind: error.code })
}
nom::Err::Incomplete(_) | nom::Err::Failure(_) => unreachable!(),
},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nginx_stub_status_try_from() {
let data = "Active connections: 291 \n\
server accepts handled requests\n \
16630948 16630948 31070465 \n\
Reading: 6 Writing: 179 Waiting: 106 \n";
assert_eq!(
NginxStubStatus::try_from(data).expect("valid data"),
NginxStubStatus {
active: 291,
accepts: 16630948,
handled: 16630948,
requests: 31070465,
reading: 6,
writing: 179,
waiting: 106
}
);
}
}