1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use env_proxy;
use reqwest;
use semver;
use serde_json as json;
use std::time::Duration;
use error::*;
const REGISTRY_HOST: &str = "https://crates.io";
#[derive(Deserialize)]
struct Versions {
versions: Vec<CrateVersion>,
}
#[derive(Deserialize)]
struct CrateVersion {
#[serde(rename = "crate")] _name: String,
#[serde(rename = "num")] version: semver::Version,
yanked: bool,
}
pub fn get_latest_version() -> Result<String> {
let crate_versions = fetch_cratesio(&format!("/crates/amethyst_tools"))?;
let dep = crate_versions
.versions
.iter()
.find(|&v| !v.yanked)
.ok_or(ErrorKind::FetchVersionFailure)?
.version
.to_string();
Ok(dep.to_owned())
}
fn fetch_cratesio(path: &str) -> Result<Versions> {
let url = format!("{host}/api/v1{path}", host = REGISTRY_HOST, path = path);
let response =
get_with_timeout(&url, get_default_timeout()).chain_err(|| ErrorKind::FetchVersionFailure)?;
let version: Versions =
json::from_reader(response).chain_err(|| ErrorKind::InvalidCratesIoJson)?;
Ok(version)
}
fn get_default_timeout() -> Duration {
Duration::from_secs(5)
}
fn get_with_timeout(url: &str, timeout: Duration) -> reqwest::Result<reqwest::Response> {
let client = reqwest::ClientBuilder::new()?
.timeout(timeout)
.proxy(reqwest::Proxy::custom(|url| {
env_proxy::for_url(url).to_url()
}))
.build()?;
client.get(url)?.send()
}