cfg_async! {
use super::rate_limit::{PreviousRate, RateLimitedEncoder};
use crate::rate_limit::{RateClass, RateLimit};
use std::{
collections::{HashMap, VecDeque},
time::Duration,
};
pub struct Channel {
pub(crate) name: String,
pub(crate) rate_limited: RateLimitedEncoder,
pub(crate) previous: Option<PreviousRate>,
pub(crate) rated_limited_at: Option<std::time::Instant>,
}
impl std::fmt::Debug for Channel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Channel").field("name", &self.name).finish()
}
}
impl Channel {
pub(crate) fn new(name: String) -> Self {
let rate_limit = RateLimit::from_class(RateClass::Regular);
let rate_limited = RateLimitedEncoder {
rate_limit,
queue: VecDeque::new(),
};
Self {
name,
rate_limited,
previous: None,
rated_limited_at: None,
}
}
pub fn set_rate_class(&mut self, rate_class: RateClass) {
self.rate_limited.rate_limit = RateLimit::from_class(rate_class);
self.rated_limited_at.take();
}
pub fn enable_slow_mode(&mut self, duration: u64) {
let rate = &mut self.rate_limited.rate_limit;
self.previous.replace(PreviousRate {
cap: rate.get_cap(),
period: rate.get_period(),
});
rate.set_period(Duration::from_secs(duration))
}
pub fn disable_slow_mode(&mut self) {
let PreviousRate { cap, period } = self.previous.take().unwrap_or_default();
let rate = &mut self.rate_limited.rate_limit;
rate.set_cap(cap);
rate.set_period(period);
}
pub fn set_rate_limited(&mut self) {
self.rate_limited.rate_limit.set_cap(1);
self.rated_limited_at.replace(std::time::Instant::now());
}
pub fn reset_rate_limit(&mut self) {
let PreviousRate { cap, period } = self.previous.take().unwrap_or_default();
self.rate_limited.rate_limit = RateLimit::full(cap, period);
self.rated_limited_at.take();
}
}
#[derive(Debug, Default)]
pub struct Channels {
pub map: HashMap<String, Channel>,
}
impl Channels {
pub fn is_on(&self, name: &str) -> bool {
self.map.contains_key(name)
}
pub fn get_mut(&mut self, name: &str) -> Option<&mut Channel> {
self.map.get_mut(name)
}
pub fn add(&mut self, name: &str) {
if self.map.contains_key(name) {
return;
}
let channel = Channel::new(name.to_string());
self.map.insert(name.to_string(), channel);
}
pub fn remove(&mut self, name: &str) {
self.map.remove(name);
}
}
}