use crate::error::{Error, Result};
pub const API_HOST: &str = "www.atonline.com";
fn connect_url() -> String {
format!("https://{API_HOST}/_special/rest/Spot:connect")
}
fn parse_hosts(status: u16, body: &[u8]) -> Result<(Vec<String>, u32)> {
if status != 200 {
return Err(Error::Api(format!("Spot:connect returned status {status}")));
}
let v: serde_json::Value =
serde_json::from_slice(body).map_err(|e| Error::Api(e.to_string()))?;
if v["result"].as_str() != Some("success") {
let msg = v["error"].as_str().unwrap_or("unknown api error");
return Err(Error::Api(msg.to_string()));
}
let data = &v["data"];
let hosts = data["hosts"]
.as_array()
.map(|a| {
a.iter()
.filter_map(|h| h.as_str().map(str::to_string))
.collect::<Vec<_>>()
})
.unwrap_or_default();
let min_conn = data["min_conn"].as_u64().unwrap_or(0) as u32;
Ok((hosts, min_conn))
}
#[cfg(feature = "native")]
pub fn get_hosts() -> Result<(Vec<String>, u32)> {
let res = rsurl::get(connect_url()).map_err(|e| Error::Api(e.to_string()))?;
parse_hosts(res.status, &res.body)
}
#[cfg(not(feature = "native"))]
pub async fn get_hosts() -> Result<(Vec<String>, u32)> {
let res = rsurl::aio::get(&connect_url())
.await
.map_err(|e| Error::Api(e.to_string()))?;
parse_hosts(res.status, &res.body)
}