ort_core/
latency.rs

1use std::time::Duration;
2
3pub type Distribution = crate::Distribution<Latency>;
4
5#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
6pub struct Latency {
7    millis: u64,
8}
9
10impl From<u64> for Latency {
11    fn from(millis: u64) -> Self {
12        Self { millis }
13    }
14}
15
16impl From<Latency> for u64 {
17    fn from(Latency { millis }: Latency) -> u64 {
18        millis
19    }
20}
21
22impl std::str::FromStr for Latency {
23    type Err = crate::InvalidDuration;
24
25    fn from_str(s: &str) -> Result<Self, Self::Err> {
26        let d = crate::parse_duration(s)?;
27        Ok((d.as_millis() as u64).into())
28    }
29}
30
31impl rand::distributions::Distribution<Duration> for Distribution {
32    fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Duration {
33        let Latency { millis } = self.get(rng.gen());
34        Duration::from_millis(millis)
35    }
36}
37
38// === parse_duration ===
39
40pub fn parse_duration(s: &str) -> Result<Duration, InvalidDuration> {
41    use regex::Regex;
42
43    let re = Regex::new(r"^\s*(\d+)(ms|s)?\s*$").expect("duration regex");
44    let cap = re.captures(s).ok_or(InvalidDuration(()))?;
45    let magnitude = cap[1].parse().map_err(|_| InvalidDuration(()))?;
46    match cap.get(2).map(|m| m.as_str()) {
47        None if magnitude == 0 => Ok(Duration::from_millis(0)),
48        Some("ms") => Ok(Duration::from_millis(magnitude)),
49        Some("s") => Ok(Duration::from_secs(magnitude)),
50        _ => Err(InvalidDuration(())),
51    }
52}
53
54#[derive(Copy, Clone, Debug)]
55pub struct InvalidDuration(());
56
57impl std::fmt::Display for InvalidDuration {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        write!(f, "invalid duration")
60    }
61}
62
63impl std::error::Error for InvalidDuration {}