assist 0.1.0

assist.org rust analysis
Documentation
use std::sync::{Arc, Mutex};

use assist::{Agreement, Institutions};
use futures::{stream::FuturesUnordered, StreamExt};
use serde_json::Value;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let institutions = reqwest::get("https://assist.org/api/institutions").await.unwrap().json::<Vec<Institutions>>().await.unwrap();
    let ids = institutions.clone().into_iter().map(|x| x.id as usize).collect::<Vec<usize>>();
    let vec_size = ids.into_iter().max().unwrap() + 1;
    let mut relations = Vec::with_capacity(vec_size);
    for _ in 0..vec_size {
        relations.push(vec![]);
    };
    for i in institutions {
        let agreements = reqwest::get(format!("https://assist.org/api/institutions/{}/agreements", i.id)).await.unwrap().json::<Vec<Agreement>>().await.unwrap();
        let mut years = vec![];
        for _ in 0..vec_size {
            years.push(0);
        };
        for agree in agreements {
            if agree.sending_year_ids.last().is_some() {
                years[agree.institution_parent_id as usize] = agree.sending_year_ids.last().unwrap().clone();
            }
        }
        relations[i.id as usize] = years;
    }
    /*for i in 0..=relations.len()-1 {
        println!("{}: {:?}", i, relations[i]);
    }
    let mut pairs = Vec::new();
    for i in 0..=vec_size-1 {
        for j in i..=vec_size-1 {
            if i != j && !relations[i].is_empty() && relations[i][j] != 0 {
                pairs.push(((i, j), relations[i][j]));
            }
        }
    }
    println!("{:#?}", pairs);*/
    let urls = Arc::new(Mutex::new(Vec::new()));
    let mut futs = FuturesUnordered::new();
    let mut outputs = Vec::new();
    let threads = 64;
    let relations = Arc::new(relations);
    for i in 1..=relations.len()-1 {
        if !relations[i].is_empty() {
            for j in 1..=relations.len()-1 {
                if i != j && relations[i][j] != 0 {
                    if relations[i][j] >= 74 {
                        let urls = Arc::clone(&urls);
                        let relations = Arc::clone(&relations);
                        let fut = async move {
                            let url;
                            if reqwest::get(format!("https://assist.org/api/articulation/Agreements?Key={}/{}/to/{}/AllPrefixes", relations[i][j], j, i).clone()).await.unwrap().json::<Value>().await.unwrap().get("isSuccessful").unwrap().to_string().parse::<bool>().unwrap() {
                                url = format!("https://assist.org/api/articulation/Agreements?Key={}/{}/to/{}/AllPrefixes", relations[i][j], j, i);
                            } else if reqwest::get(format!("https://assist.org/api/articulation/Agreements?Key={}/{}/to/{}/AllDepartments", relations[i][j], j, i).clone()).await.unwrap().json::<Value>().await.unwrap().get("isSuccessful").unwrap().to_string().parse::<bool>().unwrap() {
                                url = format!("https://assist.org/api/articulation/Agreements?Key={}/{}/to/{}/AllDepartments", relations[i][j], j, i);
                            } else if reqwest::get(format!("https://assist.org/api/articulation/Agreements?Key={}/{}/to/{}/AllMajors", relations[i][j], j, i).clone()).await.unwrap().json::<Value>().await.unwrap().get("isSuccessful").unwrap().to_string().parse::<bool>().unwrap() {
                                url = format!("https://assist.org/api/articulation/Agreements?Key={}/{}/to/{}/AllMajors", relations[i][j], j, i);
                            } else {
                                url = format!("Error: https://assist.org/api/articulation/Agreements?Key={}/{}/to/{}/AllMajors", relations[i][j], j, i);
                            }
                            eprintln!("{}", url);
                            urls.lock().unwrap().push(url.clone());
                        };
                        futs.push(fut);
                        if futs.len() == threads {
                            outputs.push(futs.next().await.unwrap());
                        }
                    }
                }
            }
        }
    };

    while let Some(item) = futs.next().await {
        outputs.push(item);
    }

    let mut sorted_urls: Vec<String> = urls.lock().unwrap().to_vec();
    sorted_urls.sort();
    println!("{}", serde_json::to_string_pretty(&sorted_urls).unwrap());
    Ok(())
}