maxbot 0.2.2

Автоматизация работы с чат-ботами на платформе MAX (max.ru)
Documentation
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{OnceLock, RwLock};

static GLOBAL_BASE_URL: OnceLock<RwLock<String>> = OnceLock::new();
static GLOBAL_MAX_RPS: AtomicUsize = AtomicUsize::new(30);

/// Устанавливает глобальный базовый URL API для всех клиентов.
///
/// По умолчанию используется `"https://platform-api.max.ru"`. Вызов этой функции
/// переопределяет URL для всех существующих и будущих экземпляров [`MaxClient`][crate::MaxClient],
/// если они не задали собственный базовый URL через [`MaxClient::set_base_url`].
///
/// # Аргументы
///
/// * `url` - новый базовый URL (например, `"https://custom.max.api"`).
///
/// # Примеры
///
/// ```
/// use maxbot::config::set_global_base_url;
///
/// set_global_base_url("https://sandbox-api.max.ru");
/// ```
pub fn set_global_base_url(url: impl Into<String>) {
    let lock = GLOBAL_BASE_URL
        .get_or_init(|| RwLock::new("https://platform-api.max.ru".to_string()));
    let mut guard = lock.write().unwrap();
    *guard = url.into();
}

/// Возвращает текущий глобальный базовый URL.
///
/// Значение по умолчанию — `"https://platform-api.max.ru"`.
pub fn get_global_base_url() -> String {
    let lock = GLOBAL_BASE_URL
        .get_or_init(|| RwLock::new("https://platform-api.max.ru".to_string()));
    lock.read().unwrap().clone()
}

/// Устанавливает глобальное ограничение частоты запросов (RPS).
///
/// Это значение используется всеми клиентами, у которых не задан собственный лимит
/// (см. [`MaxClient::set_max_rps`][crate::MaxClient::set_max_rps]).
///
/// # Аргументы
///
/// * `rps` - количество запросов в секунду. Значение `0` отключает ограничение.
///
/// # Примеры
///
/// ```
/// use maxbot::config::set_global_max_rps;
///
/// set_global_max_rps(50);  // 50 запросов в секунду
/// set_global_max_rps(0);   // без ограничений
/// ```
///
/// Примечание: в документации MAX рекомендуется не превышать 30 rps для стабильной
/// работы бота, но по факту иногда не выдерживает и 10 rps. По наблюдениям, лучше
/// вообще отправлять не чаще одного раза в секунду.
pub fn set_global_max_rps(rps: usize) {
    GLOBAL_MAX_RPS.store(rps, Ordering::Relaxed);
}

/// Возвращает текущее глобальное ограничение RPS.
///
/// Значение по умолчанию — `30`.
pub fn get_global_max_rps() -> usize {
    GLOBAL_MAX_RPS.load(Ordering::Relaxed)
}