developer_disk_image 0.1.0

A port of https://github.com/doronz88/DeveloperDiskImage to Rust
Documentation
// fuck transphobes
use serde::Deserialize;
use base64::prelude::*;

const DEVELOPER_DISK_IMAGE_REPO_TREE_URL: &str = "https://api.github.com/repos/doronz88/DeveloperDiskImage/git/trees/main?recursive=true";

pub struct DeveloperDiskImage {
    pub image: Vec<u8>,
    pub signature: Vec<u8>,
}

pub struct PersonalizedImage {
    pub image: Vec<u8>,
    pub build_manifest: Vec<u8>,
    pub trustcache: Vec<u8>,
}

#[derive(Debug, Clone)]
pub struct DeveloperDiskImageRepository {
    pub path_urls: std::collections::HashMap<String, String>,
}

#[derive(Debug, Deserialize)]
struct DevelopDiskRepoItem {
    pub url: String,
    pub path: String,
}

#[derive(Debug, Deserialize)]
struct DevelopDiskImageRepoTreeParse {
    pub tree: Vec<DevelopDiskRepoItem>
}

#[derive(Debug, Deserialize)]
pub struct GitHubBlob {
    pub content: String,
}

impl DeveloperDiskImageRepository {
    pub fn new() -> Result<DeveloperDiskImageRepository, reqwest::Error> {
        Ok(DeveloperDiskImageRepository::new_tree(match DeveloperDiskImageRepository::query() {
            Ok(r) => r,
            Err(r) => return Err(r)
        }))
    }

    fn new_tree(tree: DevelopDiskImageRepoTreeParse) -> DeveloperDiskImageRepository {
        let mut path_urls = std::collections::HashMap::new();

        for item in tree.tree {
            path_urls.insert(item.path, item.url);
        }

        DeveloperDiskImageRepository {
            path_urls
        }
    }

    fn query() -> Result<DevelopDiskImageRepoTreeParse, reqwest::Error> {
        let res: DevelopDiskImageRepoTreeParse = match match reqwest::blocking::get(DEVELOPER_DISK_IMAGE_REPO_TREE_URL){
            Ok(r) => r,
            Err(e) => return Err(e)
        }.json() {
            Ok(r) => r,
            Err(e) => return Err(e)
        };

        Ok(res)
    }

    pub fn downloaddmg(url: String) -> Result<GitHubBlob, reqwest::Error> {
        let res: GitHubBlob = match match reqwest::blocking::get(url) {
            Ok(r) => r,
            Err(e) => return Err(e)
        }.json() {
            Ok(r) => r,
            Err(e) => return Err(e)
        };

        Ok(res)
    }

    pub fn get_developer_disk_image(self: &DeveloperDiskImageRepository, version: String) -> Option<DeveloperDiskImage> {
        let image = self.get_blob(format!("DeveloperDiskImages/{version}/DeveloperDiskImage.dmg"));
        let signature = self.get_blob(format!("DeveloperDiskImages/{version}/DeveloperDiskImage.dmg.signature"));

        if image.is_none() {
            return None;
        }

        Some(DeveloperDiskImage {
            image: image.unwrap(),
            signature: signature.unwrap()
        })
    }

    pub fn get_personalized_disk_image(self: &DeveloperDiskImageRepository) -> PersonalizedImage {
        let image = self.get_blob("PersonalizedImages/Xcode_iOS_DDI_Personalized/Image.dmg".to_owned());
        let build_manifest = self.get_blob("PersonalizedImages/Xcode_iOS_DDI_Personalized/BuildManifest.plist".to_owned());
        let trustcache = self.get_blob("PersonalizedImages/Xcode_iOS_DDI_Personalized/Image.dmg.trustcache".to_owned());

        PersonalizedImage {
            image: image.unwrap(),
            build_manifest: build_manifest.unwrap(),
            trustcache: trustcache.unwrap()
        }
    }

    pub fn get_blob(self: &DeveloperDiskImageRepository, path: String) -> Option<Vec<u8>> {
        let url = self.path_urls.get(&path);
        
        if url.is_none() {
            return None;
        }

        Some(BASE64_STANDARD.decode(DeveloperDiskImageRepository::downloaddmg(url.unwrap().to_string()).unwrap().content).unwrap())
        
    }
}