developer_disk_image/
lib.rs

1// fuck transphobes
2use serde::Deserialize;
3use base64::prelude::*;
4
5const DEVELOPER_DISK_IMAGE_REPO_TREE_URL: &str = "https://api.github.com/repos/doronz88/DeveloperDiskImage/git/trees/main?recursive=true";
6
7pub struct DeveloperDiskImage {
8    pub image: Vec<u8>,
9    pub signature: Vec<u8>,
10}
11
12pub struct PersonalizedImage {
13    pub image: Vec<u8>,
14    pub build_manifest: Vec<u8>,
15    pub trustcache: Vec<u8>,
16}
17
18#[derive(Debug, Clone)]
19pub struct DeveloperDiskImageRepository {
20    pub path_urls: std::collections::HashMap<String, String>,
21}
22
23#[derive(Debug, Deserialize)]
24struct DevelopDiskRepoItem {
25    pub url: String,
26    pub path: String,
27}
28
29#[derive(Debug, Deserialize)]
30struct DevelopDiskImageRepoTreeParse {
31    pub tree: Vec<DevelopDiskRepoItem>
32}
33
34#[derive(Debug, Deserialize)]
35pub struct GitHubBlob {
36    pub content: String,
37}
38
39impl DeveloperDiskImageRepository {
40    pub fn new() -> Result<DeveloperDiskImageRepository, reqwest::Error> {
41        Ok(DeveloperDiskImageRepository::new_tree(match DeveloperDiskImageRepository::query() {
42            Ok(r) => r,
43            Err(r) => return Err(r)
44        }))
45    }
46
47    fn new_tree(tree: DevelopDiskImageRepoTreeParse) -> DeveloperDiskImageRepository {
48        let mut path_urls = std::collections::HashMap::new();
49
50        for item in tree.tree {
51            path_urls.insert(item.path, item.url);
52        }
53
54        DeveloperDiskImageRepository {
55            path_urls
56        }
57    }
58
59    fn query() -> Result<DevelopDiskImageRepoTreeParse, reqwest::Error> {
60        let res: DevelopDiskImageRepoTreeParse = match match reqwest::blocking::get(DEVELOPER_DISK_IMAGE_REPO_TREE_URL){
61            Ok(r) => r,
62            Err(e) => return Err(e)
63        }.json() {
64            Ok(r) => r,
65            Err(e) => return Err(e)
66        };
67
68        Ok(res)
69    }
70
71    pub fn downloaddmg(url: String) -> Result<GitHubBlob, reqwest::Error> {
72        let res: GitHubBlob = match match reqwest::blocking::get(url) {
73            Ok(r) => r,
74            Err(e) => return Err(e)
75        }.json() {
76            Ok(r) => r,
77            Err(e) => return Err(e)
78        };
79
80        Ok(res)
81    }
82
83    pub fn get_developer_disk_image(self: &DeveloperDiskImageRepository, version: String) -> Option<DeveloperDiskImage> {
84        let image = self.get_blob(format!("DeveloperDiskImages/{version}/DeveloperDiskImage.dmg"));
85        let signature = self.get_blob(format!("DeveloperDiskImages/{version}/DeveloperDiskImage.dmg.signature"));
86
87        if image.is_none() {
88            return None;
89        }
90
91        Some(DeveloperDiskImage {
92            image: image.unwrap(),
93            signature: signature.unwrap()
94        })
95    }
96
97    pub fn get_personalized_disk_image(self: &DeveloperDiskImageRepository) -> PersonalizedImage {
98        let image = self.get_blob("PersonalizedImages/Xcode_iOS_DDI_Personalized/Image.dmg".to_owned());
99        let build_manifest = self.get_blob("PersonalizedImages/Xcode_iOS_DDI_Personalized/BuildManifest.plist".to_owned());
100        let trustcache = self.get_blob("PersonalizedImages/Xcode_iOS_DDI_Personalized/Image.dmg.trustcache".to_owned());
101
102        PersonalizedImage {
103            image: image.unwrap(),
104            build_manifest: build_manifest.unwrap(),
105            trustcache: trustcache.unwrap()
106        }
107    }
108
109    pub fn get_blob(self: &DeveloperDiskImageRepository, path: String) -> Option<Vec<u8>> {
110        let url = self.path_urls.get(&path);
111        
112        if url.is_none() {
113            return None;
114        }
115
116        Some(BASE64_STANDARD.decode(DeveloperDiskImageRepository::downloaddmg(url.unwrap().to_string()).unwrap().content).unwrap())
117        
118    }
119}