53 lines
1.3 KiB
Rust
53 lines
1.3 KiB
Rust
use serde::Deserialize;
|
|
use std::error::Error;
|
|
use std::fmt::Write;
|
|
use std::fs;
|
|
use std::path::PathBuf;
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
struct Page {
|
|
crates: Vec<Crate>,
|
|
meta: Meta,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
struct Crate {
|
|
name: String,
|
|
max_version: String,
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
struct Meta {
|
|
next_page: String,
|
|
}
|
|
|
|
pub(crate) fn fetch(output: PathBuf, number: usize) -> Result<(), Box<dyn Error>> {
|
|
let agent = ureq::builder()
|
|
.user_agent("clippy/lintcheck (github.com/rust-lang/rust-clippy/)")
|
|
.build();
|
|
|
|
let mut crates = Vec::with_capacity(number);
|
|
let mut query = "?sort=recent-downloads&per_page=100".to_string();
|
|
while crates.len() < number {
|
|
let page: Page = agent
|
|
.get(&format!("https://crates.io/api/v1/crates{query}"))
|
|
.call()?
|
|
.into_json()?;
|
|
|
|
query = page.meta.next_page;
|
|
crates.extend(page.crates);
|
|
crates.truncate(number);
|
|
|
|
let width = number.ilog10() as usize + 1;
|
|
println!("Fetched {:>width$}/{number} crates", crates.len());
|
|
}
|
|
|
|
let mut out = "[crates]\n".to_string();
|
|
for Crate { name, max_version } in crates {
|
|
writeln!(out, "{name} = {{ name = '{name}', version = '{max_version}' }}").unwrap();
|
|
}
|
|
fs::write(output, out)?;
|
|
|
|
Ok(())
|
|
}
|