open_launcher 1.2.0

Open Launcher is a package to install and launch modded and vanilla Minecraft instances totally automatically with Rust.
Documentation
use async_recursion::async_recursion;
use sha1::Digest;
use std::error::Error;
use tokio::fs;
use tokio::io::AsyncWriteExt;

#[async_recursion]
pub(crate) async fn try_download_file(
    url: &str,
    path: &std::path::Path,
    hash: &str,
    retries: u32,
) -> Result<(), Box<dyn Error>> {
    let url = url.replace(std::path::MAIN_SEPARATOR_STR, "/");
    let url = url.as_str();

    let response = reqwest::get(url).await?;
    let data = response.bytes().await?;

    let mut file = fs::File::create(path).await?;
    file.write_all(&data).await?;

    if hash.len() != 40 {
        return Ok(());
    }

    let downloaded_hash = format!("{:x}", sha1::Sha1::digest(&fs::read(path).await?));

    if downloaded_hash != hash {
        if retries > 0 {
            fs::remove_file(path).await?;
            try_download_file(url, path, hash, retries - 1).await?;
        } else {
            return Err("Hash mismatch".into());
        }
    }

    Ok(())
}

pub(crate) fn get_os() -> String {
    match std::env::consts::OS {
        "windows" => "windows".to_string(),
        "macos" => "osx".to_string(),
        "linux" => "linux".to_string(),
        _ => std::env::consts::OS.to_string(),
    }
}