uranium-rs 1.0.3

Lib for downloading/making minecraft and modpacks
Documentation
use std::fs;

use mine_data_structs::minecraft::RUNTIMES_URL;
use mine_data_structs::minecraft::{get_minecraft_path, RuntimeFiles, Runtimes};
use reqwest::Client;

use super::DownloadableObject;
use crate::downloaders::{Downloader, FileDownloader, HashType};
use crate::error::{Result, UraniumError};

pub struct RuntimeDownloader {
    runtime: String,
}

impl RuntimeDownloader {
    pub fn new(runtime: String) -> Self {
        Self { runtime }
    }

    pub async fn download(&mut self) -> Result<()> {
        let client = Client::new();
        let x = client
            .get(RUNTIMES_URL)
            .send()
            .await?
            .text()
            .await?;

        let val: Runtimes = serde_json::from_str(&x).unwrap();

        let runtime_url = val
            .linux
            .get(&self.runtime)
            .ok_or(UraniumError::other("No runtime found"))?
            .first()
            .ok_or(UraniumError::other(
                "Mojang doesn't know about their own runtime",
            ))?
            .get_url();

        let runtime_files: RuntimeFiles = client
            .get(runtime_url)
            .send()
            .await?
            .json()
            .await?;

        let os = std::env::consts::OS;

        let minecraft_root = get_minecraft_path().unwrap();
        let runtime_path =
            minecraft_root.join(format!("runtime/{}/{}/{}", self.runtime, os, self.runtime));

        let executables_files = runtime_files
            .files
            .iter()
            .filter(|(_, item)| item.executable)
            .map(|(s, _)| runtime_path.join(s));

        #[cfg(target_os = "linux")]
        {
            use std::os::unix::fs::PermissionsExt;
            executables_files
                .flat_map(fs::metadata)
                .for_each(|metadata| {
                    metadata
                        .permissions()
                        .set_mode(0o766)
                });
        }

        let objects: Vec<DownloadableObject> = runtime_files
            .files
            .into_iter()
            .filter(|(_, s)| s.file_type == "file")
            .map(|(k, mut s)| {
                let raw = s
                    .downloads
                    .remove("raw")
                    .unwrap();
                (runtime_path.join(k), raw.url, raw.sha1)
            })
            .map(|(k, s, h)| DownloadableObject::new(&s, &k, Some(HashType::Sha1(h.to_string()))))
            .collect();

        let mut downloader = Downloader::new(objects);
        downloader.complete().await?;

        Ok(())
    }
}