cmd_wrk_parser/type_parsers/
std.rs1use std::net::IpAddr;
2use std::str::FromStr;
3use std::time::Duration;
4
5use lazy_static::lazy_static;
6
7use crate::{TypeParser, Error, TypeParseResult, utils};
8use regex::Regex;
9
10lazy_static! {
11 static ref DURATION_FMT_1: Regex = Regex::new(
12 r"((?P<Hour>\d{1,4}):)?(?P<Minute>\d{1,2}):(?P<Second>\d{1,2})(\.(?P<Milli>\d{1,3}))?"
13 ).unwrap();
14
15 static ref DURATION_FMT_2: Regex = Regex::new(r"(\d{1,4})(y|M|w|d|h|m|s|ms|ns)").unwrap();
16}
17
18pub struct IpParser;
19
20impl TypeParser for IpParser {
21 type Type = IpAddr;
22 type Context = ();
23
24 fn parse(&self, _ctx: &Self::Context, src: &str) -> TypeParseResult<Self::Type> {
25 let s = match utils::take_until_whitespace(src) {
26 Some(s) => s,
27 None => return Err(Error::UnexpectedToken(0)),
28 };
29
30 let val = IpAddr::from_str(s)?;
31
32 Ok((val, s.len()))
33 }
34}
35
36pub struct DurationParser;
37
38impl TypeParser for DurationParser {
39 type Type = Duration;
40 type Context = ();
41
42 fn parse(&self, _ctx: &Self::Context, src: &str) -> TypeParseResult<Self::Type> {
43 let mut out = Duration::new(0, 0);
44
45 if let Some(c) = DURATION_FMT_1.captures(src) {
46 if let Some(hour) = c.name("Hour") {
47 out += Duration::from_secs(u64::from_str(hour.as_str())? * 3600);
48 }
49
50 if let Some(min) = c.name("Minute") {
51 out += Duration::from_secs(u64::from_str(min.as_str())? * 60);
52 }
53
54 if let Some(sec) = c.name("Second") {
55 out += Duration::from_secs(u64::from_str(sec.as_str())?);
56 }
57
58 if let Some(ms) = c.name("Milli") {
59 out += Duration::from_millis(u64::from_str(ms.as_str())?);
60 }
61
62 let len = c[0].len();
63
64 return Ok((out, len))
65 }
66
67 let mut counter = 0u8;
68 let mut end: usize = 0;
69
70 for (i, c) in DURATION_FMT_2.captures_iter(src).enumerate() {
71 if counter == 0 && i == 0 {
72 continue
73 } else { counter += 1 }
74
75 let mut val = u64::from_str(c.get(1).unwrap().as_str())?;
76
77 match c.get(2).unwrap().as_str() {
78 "y" => val *= 1_000_000 * 1_000 * 60 * 60 * 24 * 30 * 12,
79 "M" => val *= 1_000_000 * 1_000 * 60 * 60 * 24 * 30,
80 "w" => val *= 1_000_000 * 1_000 * 60 * 60 * 24 * 7,
81 "d" => val *= 1_000_000 * 1_000 * 60 * 60 * 24,
82 "h" => val *= 1_000_000 * 1_000 * 60 * 60,
83 "m" => val *= 1_000_000 * 1_000 * 60,
84 "s" => val *= 1_000_000 * 1_000,
85 "ms" => val *= 1_000_000,
86 "ns" => (),
87 _ => unreachable!(),
88 }
89
90 out += Duration::from_nanos(val);
91
92 end = c[0].len();
93 }
94
95 if counter > 0 {
96 Ok((out, end))
97 } else {
98 Err(Error::InvalidFormat(String::from("unable to process duration")))
99 }
100 }
101}
102
103pub struct StringParser;
104
105impl TypeParser for StringParser {
106 type Type = String;
107 type Context = ();
108
109 fn parse(&self, _ctx: &Self::Context, src: &str) -> TypeParseResult<Self::Type> where
110 {
111 let s = if let Some(s) = utils::take_until_close_quote(src) { s }
112 else { utils::take_until_whitespace(src).unwrap() };
113
114 Ok((String::from(s), s.len()))
115 }
116}