developer_disk_image/
lib.rs1use 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}