amqpsy 0.1.0

Extremely opinionated AMQP PubSub library
Documentation
use rand::Rng;
use std::{env::var, str::FromStr};

#[derive(Debug, Clone, Copy)]
pub struct Chaos {
    publisher_duplicate_percentage: u8,
    publisher_failure_percentage: u8,
}

impl Chaos {
    pub fn new() -> Self {
        let configs = std::env::vars()
            .filter(|(k, _)| k.starts_with("AMQPSY_CHAOS_"))
            .count();
        if configs == 0 {
            panic!("amqpsy: When the `chaos` feature is turned on, you must start the app with one of the chaos parameter passed as environment variable (`AMQPSY_CHAOS_*`). See the `Chaos` section of the readme.")
        }

        Self {
            publisher_duplicate_percentage: from_env_or_default(
                "AMQPSY_CHAOS_PUBLISHER_DUPLICATE_PERCENTAGE",
            ),
            publisher_failure_percentage: from_env_or_default(
                "AMQPSY_CHAOS_PUBLISHER_FAILURE_PERCENTAGE",
            ),
        }
    }

    pub fn should_publish_fail(&self) -> bool {
        true_percentage_of_time(self.publisher_failure_percentage)
    }

    pub fn should_publish_duplicate(&self) -> bool {
        true_percentage_of_time(self.publisher_duplicate_percentage)
    }
}

fn from_env_or_default<T: FromStr + Default>(p: &str) -> T {
    var(p)
        .ok()
        .and_then(|v| v.parse::<T>().ok())
        .unwrap_or_default()
}

fn between<T>(min: T, max: T) -> T
where
    T: rand::distributions::uniform::SampleUniform + Eq + PartialOrd,
{
    rand::thread_rng().gen_range(min..max)
}

fn true_percentage_of_time(percent: u8) -> bool {
    if percent == 0 {
        return false;
    }

    debug_assert!(percent <= 100);
    between(1, 100) <= percent as _
}