oni_simulator 0.1.2

Networking simulator
Documentation
use rand::{
    prelude::*,
    distributions::{Distribution, Uniform},
};
use std::time::{Instant, Duration};

const ZERO: Duration = Duration::from_secs(0);
const ONE: Duration = Duration::from_secs(1);

#[derive(Debug, Default, Clone, Copy)]
pub struct Config {
    pub latency: Duration,
    pub jitter: Duration,
    pub loss: f64,
    pub duplicate: f64,
}

impl Config {
    crate fn delivery<R>(&self, rng: &mut R, delivery: Instant) -> Option<Instant>
        where R: Rng + ?Sized
    {
        if self.loss > Uniform::new(0.0, 100.0).sample(rng) {
            return None;
        }

        let delivery = delivery + self.latency;

        if self.jitter == ZERO {
            Some(delivery)
        } else {
            let dt = Uniform::new(ZERO, self.jitter).sample(rng);
            if rng.gen() {
                Some(delivery + dt)
            } else {
                Some(delivery - dt)
            }
        }
    }

    crate fn duplicate<R>(&self, rng: &mut R, delivery: Instant) -> Option<Instant>
        where R: Rng + ?Sized
    {
        if self.duplicate > Uniform::new(0.0, 100.0).sample(rng) {
            Some(delivery + Uniform::new(ZERO, ONE).sample(rng))
        } else {
            None
        }
    }
}