use crate::{Http, Json};
pub struct CrateInfo {
pub latest: String,
pub downloads: String,
pub total_downloads: u64,
pub versions: u64,
pub license: String,
pub created_at: String,
pub updated_at: String,
}
pub fn format_number(n: u64) -> String {
if n < 1000 {
n.to_string()
} else if n < 1_000_000 {
format!("{:.1}k", n as f64 / 1000.0)
} else {
format!("{:.1}M", n as f64 / 1_000_000.0)
}
}
pub fn crate_data(crate_name: &str) -> Result<CrateInfo, Box<dyn std::error::Error>> {
let url = format!("https://crates.io/api/v1/crates/{}", crate_name);
let res = Http::get(&url)
.header("User-Agent", "crator-client/0.1.0".to_string())
.send("")?;
let root = Json::from_str(res.body());
let metadata = &root["crate"];
let total_dl = metadata["downloads"].as_f64().unwrap_or(0.0) as u64;
let license = root["versions"][0]["license"].unwrap_or("Unknown");
Ok(CrateInfo {
latest: metadata["max_version"].to_string_raw(),
downloads: format_number(total_dl),
total_downloads: total_dl,
versions: metadata["versions"].len() as u64,
license: license,
created_at: metadata["created_at"].to_string_raw(),
updated_at: metadata["updated_at"].to_string_raw(),
})
}