pub const SHORT_STEAM_FRIEND_CODE_CHARS: [char; 16] = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 't', 'v', 'w'];
pub fn create_short_steam_friend_code(account_id: u32) -> String {
let hex = format!("{:x}", account_id);
let mut friend_code = String::with_capacity(hex.len() + 1);
for c in hex.chars() {
let digit = c.to_digit(16).unwrap_or(0) as usize;
friend_code.push(SHORT_STEAM_FRIEND_CODE_CHARS[digit]);
}
let dash_pos = friend_code.len() / 2;
if dash_pos > 0 && friend_code.len() > 1 {
friend_code.insert(dash_pos, '-');
}
friend_code
}
pub fn parse_short_steam_friend_code(friend_code: &str) -> Option<u32> {
let code = friend_code.replace('-', "");
let mut hex = String::with_capacity(code.len());
for c in code.chars() {
let pos = SHORT_STEAM_FRIEND_CODE_CHARS.iter().position(|&x| x == c)?;
hex.push(char::from_digit(pos as u32, 16).unwrap());
}
u32::from_str_radix(&hex, 16).ok()
}
pub fn parse_quick_invite_link(link: &str) -> Option<(String, String)> {
let path = link.trim().trim_start_matches("https://").trim_start_matches("http://").trim_start_matches("s.team/p/").trim_start_matches("steamcommunity.com/user/");
let parts: Vec<&str> = path.split('/').filter(|s| !s.is_empty()).collect();
if parts.len() < 2 {
return None;
}
Some((parts[0].to_string(), parts[1].to_string()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_short_steam_friend_code() {
let code = create_short_steam_friend_code(123456789);
for c in code.chars() {
assert!(SHORT_STEAM_FRIEND_CODE_CHARS.contains(&c) || c == '-');
}
assert_eq!(code.matches('-').count(), 1);
}
#[test]
fn test_parse_short_steam_friend_code_roundtrip() {
let ids = [123456789u32, 1, 999999, 2147483647];
for id in ids {
let code = create_short_steam_friend_code(id);
let parsed = parse_short_steam_friend_code(&code);
assert_eq!(parsed, Some(id), "Roundtrip failed for id {} code {}", id, code);
}
}
#[test]
fn test_parse_quick_invite_link() {
let (code, token) = parse_quick_invite_link("https://s.team/p/bcdf-ghjk/ABCD1234").unwrap();
assert_eq!(code, "bcdf-ghjk");
assert_eq!(token, "ABCD1234");
let (code, token) = parse_quick_invite_link("bcdf-ghjk/TOKEN").unwrap();
assert_eq!(code, "bcdf-ghjk");
assert_eq!(token, "TOKEN");
}
#[test]
fn test_parse_quick_invite_link_invalid() {
assert!(parse_quick_invite_link("https://s.team/p/bcdf-ghjk").is_none());
assert!(parse_quick_invite_link("").is_none());
}
}