pub mod composite;
pub mod custom;
pub mod exponential;
use serde::{Deserialize, Serialize};
use std::time::Duration;
pub trait Scenario: Send + Sync + ScenarioClone {
fn rate(&self, time_elasped: Duration) -> f32;
fn duration(&self) -> u128;
fn max_rate(&self) -> f32;
}
pub trait ScenarioClone {
fn clone_box(&self) -> Box<dyn Scenario>;
}
impl<T> ScenarioClone for T
where
T: 'static + Scenario + Clone,
{
fn clone_box(&self) -> Box<dyn Scenario> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn Scenario> {
fn clone(&self) -> Box<dyn Scenario> {
self.clone_box()
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct ConstantScenario {
pub rate: f32,
pub duration: u128,
}
impl Scenario for ConstantScenario {
fn rate(&self, _time_elasped: Duration) -> f32 {
self.rate
}
fn duration(&self) -> u128 {
self.duration
}
fn max_rate(&self) -> f32 {
self.rate
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct LinearScenario {
pub starting_rate: f32,
pub slope: f32,
pub duration: u128,
}
impl Scenario for LinearScenario {
fn rate(&self, time_elasped: Duration) -> f32 {
self.starting_rate + self.slope * time_elasped.as_millis() as f32 / 1000.
}
fn duration(&self) -> u128 {
self.duration
}
fn max_rate(&self) -> f32 {
self.starting_rate + self.slope * (self.duration as f32 / 1000.)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn constant_scenario() {
let scene = ConstantScenario {
rate: 500.,
duration: 1000,
};
assert_eq!(scene.duration(), 1000);
assert_eq!(scene.rate(Duration::from_millis(0)), 500.);
assert_eq!(scene.rate(Duration::from_millis(500)), 500.);
assert_eq!(scene.rate(Duration::from_millis(1000)), 500.);
assert_eq!(scene.max_rate(), 500.);
}
#[test]
fn linear_scenario() {
let scene = LinearScenario {
starting_rate: 0.,
slope: 100.,
duration: 20000,
};
assert_eq!(scene.duration(), 20000);
assert_eq!(scene.rate(Duration::from_millis(0)), 0.);
assert_eq!(scene.rate(Duration::from_millis(500)), 50.);
assert_eq!(scene.rate(Duration::from_millis(20000)), 2000.);
assert_eq!(scene.max_rate(), 2000.);
}
}