use serde::Deserialize;
use crate::error::{Error, Result};
const PROFILE_URL: &str = "https://api.mojang.com/users/profiles/minecraft";
const SESSION_URL: &str = "https://sessionserver.mojang.com/session/minecraft/profile";
#[derive(Deserialize)]
struct MojangProfile {
id: String,
name: String,
}
pub async fn uuid_for_username(username: &str) -> Result<Option<String>> {
Ok(fetch_profile(&format!("{PROFILE_URL}/{username}"))
.await?
.map(|p| p.id))
}
pub async fn username_for_uuid(uuid: &str) -> Result<Option<String>> {
let uuid = uuid.replace('-', "");
Ok(fetch_profile(&format!("{SESSION_URL}/{uuid}"))
.await?
.map(|p| p.name))
}
async fn fetch_profile(url: &str) -> Result<Option<MojangProfile>> {
let response = reqwest::get(url).await?;
let status = response.status();
if status.as_u16() == 404 || status.as_u16() == 204 {
return Ok(None);
}
if !status.is_success() {
return Err(Error::Api {
status: status.as_u16(),
cause: "Mojang API error".to_string(),
});
}
let bytes = response.bytes().await?;
Ok(Some(serde_json::from_slice(&bytes)?))
}