rusty_bin/monitor/collector/
utils.rs

1//! Utility functions for the data collection module.
2
3use super::types::DataType;
4use std::time::Duration;
5
6/// Generate a unique task ID for an exchange-symbol-datatype combination.
7pub fn generate_task_id(exchange: &str, symbol: &str, data_type: DataType) -> String {
8    format!("{exchange}:{symbol}:{data_type}")
9}
10
11/// Parse a task ID back into components.
12pub fn parse_task_id(task_id: &str) -> Option<(String, String, DataType)> {
13    let parts: Vec<&str> = task_id.split(':').collect();
14    if parts.len() != 3 {
15        return None;
16    }
17
18    let data_type = match parts[2] {
19        "trades" => DataType::Trades,
20        "orderbook" => DataType::OrderBook,
21        _ => return None,
22    };
23
24    Some((parts[0].to_string(), parts[1].to_string(), data_type))
25}
26
27/// Calculate exponential backoff delay.
28#[must_use]
29pub fn calculate_backoff(attempt: u32, base_ms: u64, max_ms: u64) -> Duration {
30    let delay_ms = (base_ms * 2_u64.pow(attempt)).min(max_ms);
31    Duration::from_millis(delay_ms)
32}
33
34/// Validate symbol format for a given exchange.
35#[must_use]
36pub fn validate_symbol(exchange: &str, symbol: &str) -> bool {
37    match exchange.to_lowercase().as_str() {
38        "binance" => {
39            // Binance symbols are typically like BTCUSDT
40            symbol.len() >= 6 && symbol.chars().all(|c| c.is_ascii_uppercase())
41        }
42        "upbit" => {
43            // Upbit symbols are like KRW-BTC
44            symbol.contains('-') && symbol.len() >= 5
45        }
46        "bybit" => {
47            // Bybit symbols are like BTCUSDT
48            symbol.len() >= 6 && symbol.chars().all(|c| c.is_ascii_uppercase())
49        }
50        "coinbase" => {
51            // Coinbase symbols are like BTC-USD
52            symbol.contains('-') && symbol.len() >= 5
53        }
54        "bithumb" => {
55            // Bithumb symbols are like BTC_KRW
56            symbol.contains('_') && symbol.len() >= 5
57        }
58        _ => {
59            // For unknown exchanges, just check basic format
60            !symbol.is_empty() && symbol.len() <= 20
61        }
62    }
63}