Skip to content

Instantly share code, notes, and snippets.

@boxdot
Created November 7, 2019 20:09
Show Gist options
  • Save boxdot/38e901c10026f4a6eb190e1f721ca854 to your computer and use it in GitHub Desktop.
Save boxdot/38e901c10026f4a6eb190e1f721ca854 to your computer and use it in GitHub Desktop.
Calculate number of stable crates on crates.io
use std::cmp::Reverse;
use std::collections::HashMap;
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use walkdir::WalkDir;
fn get_version(entry: walkdir::Result<walkdir::DirEntry>) -> Option<String> {
let entry = entry.ok()?;
let path = entry.path();
if !path.is_file() {
return None;
}
let file = BufReader::new(File::open(path).ok()?);
file.lines().last().map(|line| {
let line = line.ok()?;
let json: serde_json::Value = serde_json::from_str(&line).ok()?;
let version = json.as_object()?.get("vers")?.as_str()?;
Some(version.into())
})?
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let index_dir = std::env::args()
.skip(1)
.next()
.expect("USAGE: crates-stats <crates.io-index>");
let mut versions = HashMap::new();
let mut num_crates = 0;
for version in WalkDir::new(index_dir).into_iter().filter_map(get_version) {
let counter = versions.entry(version).or_insert(0);
*counter += 1;
num_crates += 1;
}
println!("Num crates: {}", num_crates);
let num_stable_crates: usize = versions
.iter()
.map(|(v, &c)| if !v.starts_with('0') { c } else { 0 })
.sum();
println!("Num stable crates: {}", num_stable_crates);
let mut versions: Vec<(usize, String)> = versions.into_iter().map(|(c, v)| (v, c)).collect();
versions.sort_by_key(|k| Reverse(k.0));
for (count, version) in &versions {
println!("{:>width$} {}", count, version, width = 5);
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment