Skip to main content

rustinsight/
crates.rs

1use crate::RI_USER_AGENT;
2use anyhow::Error;
3use reqwest::{header::USER_AGENT, Client};
4use semver::Version;
5use serde::Deserialize;
6
7const BASE: &str = "https://crates.io/api/v1/crates/knowledge";
8
9pub struct CratesApi {
10    client: Client,
11}
12
13impl CratesApi {
14    pub fn new() -> Self {
15        Self {
16            client: Client::new(),
17        }
18    }
19
20    pub async fn fetch_info(&mut self) -> Result<CratesInfo, Error> {
21        let url = format!("{BASE}");
22        let info = self
23            .client
24            .get(&url)
25            .header(USER_AGENT, RI_USER_AGENT)
26            .send()
27            .await?
28            .json()
29            .await?;
30        Ok(info)
31    }
32
33    pub async fn latest_version(&mut self) -> Result<Version, Error> {
34        self.fetch_info()
35            .await?
36            .versions
37            .into_iter()
38            .next()
39            .map(|remote| remote.num)
40            .ok_or_else(|| Error::msg("No versions avaialble"))
41    }
42}
43
44#[derive(Debug, Deserialize)]
45pub struct CratesInfo {
46    pub versions: Vec<CratesVersion>,
47}
48
49#[derive(Debug, Deserialize)]
50pub struct CratesVersion {
51    pub num: Version,
52}