|
// Synchronous |
|
use std::{ |
|
collections::HashMap, |
|
error::Error, |
|
fs::File, |
|
io::{prelude::*, BufReader}, |
|
}; |
|
|
|
fn main() -> Result<(), Box<dyn Error>> { |
|
let file = BufReader::new(File::open("top100.txt")?); |
|
|
|
let mut results = HashMap::new(); |
|
|
|
for line in file.lines() { |
|
let crate_name = line?; |
|
|
|
let url = format!("https://crates.io/api/v1/crates/{}/owners", crate_name); |
|
|
|
let json: serde_json::Value = reqwest::get(&url)?.json()?; |
|
|
|
let username = json["users"][0]["login"] |
|
.as_str() |
|
.expect(&format!("{} is not a valid crate name", crate_name)) |
|
.to_string(); |
|
|
|
*results.entry(username).or_insert(0) += 1; |
|
} |
|
|
|
let mut results: Vec<_> = results.iter().collect(); |
|
results.sort_by(|a, b| b.1.cmp(a.1)); |
|
|
|
println!("Results: {:?}", results); |
|
|
|
Ok(()) |
|
} |
|
|
|
// Asynchronous |
|
use std::{ |
|
collections::HashMap, |
|
fs::File, |
|
io::{prelude::*, BufReader}, |
|
}; |
|
|
|
use futures; |
|
use tokio::runtime::Runtime; |
|
|
|
use futures::{Future, Stream}; |
|
use reqwest::r#async::{Client, Decoder}; |
|
use std::mem; |
|
|
|
fn fetch() -> impl Future<Item = Vec<String>, Error = ()> { |
|
let file = BufReader::new(File::open("top100.txt").unwrap()); |
|
|
|
let mut futures = Vec::new(); |
|
|
|
for line in file.lines() { |
|
let crate_name = line.unwrap(); |
|
let url = format!("https://crates.io/api/v1/crates/{}/owners", crate_name); |
|
|
|
futures.push( |
|
Client::new() |
|
.get(&url) |
|
.send() |
|
.and_then(|mut res| { |
|
let body = mem::replace(res.body_mut(), Decoder::empty()); |
|
body.concat2() |
|
}) |
|
.map_err(|err| println!("request error: {}", err)) |
|
.map(move |body| { |
|
let body: serde_json::Value = serde_json::from_slice(&body).unwrap(); |
|
|
|
let username = body["users"][0]["login"] |
|
.as_str() |
|
.expect(&format!("{} is not a valid crate name", crate_name)) |
|
.to_string(); |
|
|
|
username |
|
}), |
|
); |
|
} |
|
|
|
futures::future::join_all(futures) |
|
} |
|
|
|
fn main() { |
|
let mut rt = Runtime::new().unwrap(); |
|
let results = rt.block_on(fetch()).unwrap(); |
|
|
|
let mut counts = HashMap::new(); |
|
|
|
for name in results { |
|
*counts.entry(name).or_insert(0) += 1; |
|
} |
|
|
|
let mut results: Vec<_> = counts.iter().collect(); |
|
results.sort_by(|a, b| b.1.cmp(&a.1)); |
|
|
|
println!("Results: {:?}", results); |
|
} |