use crate::error::IdentityError;
pub async fn resolve_timezone(
explicit: Option<&str>,
proxy: Option<&str>,
) -> Result<String, IdentityError> {
if let Some(tz) = explicit {
return Ok(tz.to_string());
}
fetch_timezone_from_ipapi(proxy).await
}
async fn fetch_timezone_from_ipapi(proxy: Option<&str>) -> Result<String, IdentityError> {
let mut builder = reqwest::Client::builder();
if let Some(proxy_url) = proxy {
builder = builder.proxy(
reqwest::Proxy::all(proxy_url)
.map_err(|e| IdentityError::TimezoneError(format!("invalid proxy: {e}")))?,
);
}
let client = builder
.build()
.map_err(|e| IdentityError::TimezoneError(format!("http client error: {e}")))?;
let resp: serde_json::Value = client
.get("http://ip-api.com/json/?fields=timezone")
.send()
.await
.map_err(|e| IdentityError::TimezoneError(format!("ip-api request failed: {e}")))?
.json()
.await
.map_err(|e| IdentityError::TimezoneError(format!("ip-api parse failed: {e}")))?;
resp.get("timezone")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
.ok_or_else(|| IdentityError::TimezoneError("ip-api returned no timezone".into()))
}