use dashmap::DashMap; use once_cell::sync::Lazy; use rand::{Rng, thread_rng}; static LINKS: Lazy> = Lazy::new(DashMap::new); const CHARSET: &[u8] = b"abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ#1234567890"; pub async fn add_short_link(long: &str) -> Result { let raw = generate_unique_short_link().await; LINKS.insert(raw.clone(), long.to_string()); Ok(format!( "https://omega.tensamin.net/direct/{}", format_with_dashes(&raw) )) } async fn generate_unique_short_link() -> String { loop { let short = generate_short_link().await; if !LINKS.contains_key(&short) { return short; } } } pub async fn generate_short_link() -> String { let len = short_length(); let mut rng = thread_rng(); (0..len) .map(|_| { let idx = rng.gen_range(0..CHARSET.len()); CHARSET[idx] as char }) .collect() } pub async fn get_short_link(short: &str) -> Result { let key = if short.contains("/") { short.split("/").nth(1).unwrap_or_default() } else { short }; let frag = short.replace(key, ""); let normalized = normalize_short(&key); if let Ok(t) = LINKS.get(&normalized).map(|v| v.value().clone()).ok_or(()) { Ok(format!("{}{}", t, frag)) } else { Err(()) } } /* ---------------- helpers ---------------- */ fn short_length() -> usize { let count = LINKS.len(); match count { 0..=1_999 => 4, 2_000..=999_999 => 8, _ => 12, } } fn format_with_dashes(s: &str) -> String { s.chars() .collect::>() .chunks(4) .map(|c| c.iter().collect::()) .collect::>() .join("-") } fn normalize_short(input: &str) -> String { input .chars() .filter(|c| *c != '-') .map(|c| match c { 'Q' | 'O' => '0', 'I' => 'l', _ => c, }) .collect() }