1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::measurement::{attribute::Speed, marker::Timestamp, thresholds::Thresholds};

use std::{
    fmt,
    time::{Duration, SystemTime},
};

#[derive(Clone)]
pub struct SpeedBenchmarkDef {
    name: String,
    thresholds: Option<Thresholds<Speed>>,
}

impl SpeedBenchmarkDef {
    pub fn new(name: String) -> Self {
        SpeedBenchmarkDef {
            name,
            thresholds: None,
        }
    }

    pub fn name(&self) -> String {
        self.name.clone()
    }

    pub fn with_thresholds(&mut self, thresholds: Thresholds<Speed>) -> &mut Self {
        self.thresholds = Some(thresholds);
        self
    }

    pub fn target(&mut self, duration: Duration) -> &mut Self {
        self.with_thresholds(Thresholds::<Speed>::new_speed(duration))
    }

    pub fn thresholds(&self) -> Option<&Thresholds<Speed>> {
        self.thresholds.as_ref()
    }

    pub fn no_target(&mut self) -> &mut Self {
        self.thresholds = None;
        self
    }

    pub fn start(&self) -> SpeedBenchmarkRun {
        SpeedBenchmarkRun {
            definition: self.clone(),
            start_marker: Timestamp::from(SystemTime::now()),
        }
    }
}

pub struct SpeedBenchmarkRun {
    definition: SpeedBenchmarkDef,
    start_marker: Timestamp,
}

impl SpeedBenchmarkRun {
    pub fn stop(&self) -> SpeedBenchmarkFinish {
        let stop_marker = Timestamp::from(SystemTime::now());
        SpeedBenchmarkFinish {
            definition: self.definition.clone(),
            speed: Speed::new(&self.start_marker, &stop_marker),
        }
    }

    pub fn timeout_exceeded(&self) -> bool {
        if let Some(thresholds) = &self.definition.thresholds {
            let max: Duration = thresholds.max().into();
            self.start_marker.elapsed() > max
        } else {
            false
        }
    }

    pub fn definition(&self) -> &SpeedBenchmarkDef {
        &self.definition
    }
}

pub struct SpeedBenchmarkFinish {
    definition: SpeedBenchmarkDef,
    speed: Speed,
}

impl SpeedBenchmarkFinish {
    pub fn print(&self) {
        println!("{}", &self);
    }

    pub fn new(definition: SpeedBenchmarkDef, speed: Speed) -> Self {
        Self { definition, speed }
    }
}

impl fmt::Display for SpeedBenchmarkFinish {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.definition.thresholds() {
            Some(thresholds) => write!(
                f,
                "Measurement: {}. Result: {}. Actual: {} Thresholds: {}",
                self.definition.name(),
                self.speed.against(thresholds),
                self.speed,
                thresholds,
            ),
            None => write!(
                f,
                "Measurement: {}. Value: {}",
                self.definition.name(),
                self.speed
            ),
        }
    }
}