use core::fmt;
use num_enum::TryFromPrimitive;
use serde::{Deserialize, Deserializer, Serialize};
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Hash, Serialize)]
pub struct SteamId(pub u64);
impl fmt::Display for SteamId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl SteamId {
pub fn new(value: u64) -> Self {
SteamId(value)
}
pub fn into_u64(&self) -> u64 {
self.0
}
pub fn get_account_id(&self) -> u32 {
(self.0 & 0xFFFFFFFF) as u32
}
pub fn get_universe(&self) -> Universe {
Universe::try_from((self.0 >> 56) & 0xF).unwrap_or(Universe::Invalid)
}
pub fn get_account_type(&self) -> AccountType {
AccountType::try_from((self.0 >> 52) & 0xF).unwrap_or(AccountType::Invalid)
}
pub fn to_id2_string(&self) -> String {
let id = self.get_account_id();
format!(
"STEAM_{}:{}:{}",
self.get_universe() as u64,
id & 1,
id >> 1
)
}
}
impl From<u64> for SteamId {
fn from(value: u64) -> Self {
SteamId(value)
}
}
impl From<String> for SteamId {
fn from(value: String) -> Self {
SteamId(value.parse::<u64>().unwrap())
}
}
pub fn de_steamid_from_str<'de, D>(deserializer: D) -> Result<SteamId, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(SteamId::from(s))
}
fn callback<'de, D>(deserializer: D) -> Result<SteamId, D::Error>
where
D: Deserializer<'de>,
{
Ok(SteamId::from(String::deserialize(deserializer)?))
}
#[derive(Debug, Deserialize)]
struct WrappedSteamId(#[serde(deserialize_with = "callback")] SteamId);
pub fn de_steamid_from_str_opt<'de, D>(deserializer: D) -> Result<Option<SteamId>, D::Error>
where
D: serde::Deserializer<'de>,
{
Option::<WrappedSteamId>::deserialize(deserializer).map(
|opt_wrapped: Option<WrappedSteamId>| opt_wrapped.map(|wrapped: WrappedSteamId| wrapped.0),
)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ParseSteamIdError;
impl std::fmt::Display for ParseSteamIdError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Failed to parse SteamID")
}
}
impl std::error::Error for ParseSteamIdError {}
#[derive(Copy, Clone, PartialEq, Eq, Debug, TryFromPrimitive)]
#[repr(u64)]
pub enum AccountType {
Invalid,
Individual,
Multiseat,
GameServer,
AnonGameServer,
Pending,
ContentServer,
Clan,
Chat,
P2PSuperSeeder,
AnonUser,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, TryFromPrimitive)]
#[repr(u64)]
pub enum Universe {
Invalid,
Public,
Beta,
Internal,
Dev,
}