ge_man_lib/download/
response.rs

1use serde::Deserialize;
2
3/// The compressed archive of the compatibility tool and file name.
4///
5/// For GE Proton the archive is provided as a `tar.gz` file.<br>
6/// For Wine GE the archive is provide as a `tar.xz` file.
7pub struct DownloadedArchive {
8    pub compressed_content: Vec<u8>,
9    pub file_name: String,
10}
11
12impl DownloadedArchive {
13    pub fn new(compressed_content: Vec<u8>, file_name: String) -> Self {
14        DownloadedArchive {
15            compressed_content,
16            file_name,
17        }
18    }
19}
20
21/// The expected checksum of a compatibility tool and the checksum file name.
22///
23/// The checksum is provided as a `sha512sum` file.
24pub struct DownloadedChecksum {
25    pub checksum: String,
26    pub file_name: String,
27}
28
29impl DownloadedChecksum {
30    pub fn new(checksum: String, file_name: String) -> Self {
31        DownloadedChecksum { checksum, file_name }
32    }
33}
34
35/// Assets of a GE Proton or Wine GE release.
36pub struct DownloadedAssets {
37    /// Tag name of the release.
38    pub tag: String,
39    /// The compressed archive.
40    pub compressed_archive: DownloadedArchive,
41    /// The checksum of the compressed archive.
42    ///
43    /// The `checksum` for a archive can be `None` if `download_checksum` in `DownloadRequest` is
44    /// set to false.
45    pub checksum: Option<DownloadedChecksum>,
46}
47
48impl DownloadedAssets {
49    pub fn new(tag: String, compressed_archive: DownloadedArchive, checksum: Option<DownloadedChecksum>) -> Self {
50        DownloadedAssets {
51            tag,
52            compressed_archive,
53            checksum,
54        }
55    }
56}
57
58/// Represents a GitHub API release.
59///
60/// Only the `tag_name` and `assets` of the release are relevant for us. Too see the APIs from which this struct is
61/// constructed from see the documentation of `GeDownloader::fetch_release`.
62#[derive(Debug, Deserialize)]
63pub struct GeRelease {
64    pub tag_name: String,
65    pub assets: Vec<GeAsset>,
66}
67
68impl GeRelease {
69    pub fn new(tag_name: String, assets: Vec<GeAsset>) -> Self {
70        GeRelease { tag_name, assets }
71    }
72
73    fn is_checksum_asset(asset: &GeAsset) -> bool {
74        asset.name.contains(".sha512sum")
75    }
76
77    fn is_tar_asset(asset: &GeAsset) -> bool {
78        asset.name.contains(".tar.gz")
79    }
80
81    pub fn checksum_asset(&self) -> &GeAsset {
82        self.assets
83            .iter()
84            .find(|asset| GeRelease::is_checksum_asset(asset))
85            .unwrap()
86    }
87
88    pub fn tar_asset(&self) -> &GeAsset {
89        self.assets.iter().find(|asset| GeRelease::is_tar_asset(asset)).unwrap()
90    }
91}
92
93/// An asset of a GitHub release.
94///
95/// This struct contains the URL from which the asset file can be downloaded from. Additionally, it contains the
96/// content type of the file and the file name.
97#[derive(Debug, Deserialize)]
98pub struct GeAsset {
99    /// File name of the asset.
100    pub name: String,
101    pub content_type: String,
102    pub browser_download_url: String,
103}
104
105impl GeAsset {
106    pub fn new<S: Into<String>>(name: S, content_type: S, browser_download_url: S) -> Self {
107        GeAsset {
108            name: name.into(),
109            content_type: content_type.into(),
110            browser_download_url: browser_download_url.into(),
111        }
112    }
113}
114
115impl Clone for GeAsset {
116    fn clone(&self) -> Self {
117        GeAsset {
118            name: self.name.clone(),
119            content_type: self.content_type.clone(),
120            browser_download_url: self.content_type.clone(),
121        }
122    }
123}
124
125/// Newtype for GitHub API tag name deserialization.
126#[derive(Debug, Deserialize)]
127pub(crate) struct CompatibilityToolTag {
128    name: String,
129}
130
131impl From<CompatibilityToolTag> for String {
132    fn from(tag_name: CompatibilityToolTag) -> Self {
133        String::from(tag_name.name)
134    }
135}
136
137#[cfg(test)]
138mod ge_release_tests {
139    use crate::download::mime::{APPLICATION_GZIP, APPLICATION_OCTET_STREAM, BINARY_OCTET_STREAM};
140
141    use super::*;
142
143    #[test]
144    fn get_checksum_asset_with_application_octet_stream() {
145        let tag = String::from("6.20-GE-1");
146        let assets = vec![
147            GeAsset::new("Proton-6.20-GE-1.tar.gz", APPLICATION_GZIP, "gzip"),
148            GeAsset::new("Proton-6.20-GE-1.sha512sum", APPLICATION_OCTET_STREAM, "octet"),
149        ];
150        let release = GeRelease::new(tag, assets);
151
152        let checksum_asset = release.checksum_asset();
153        assert_eq!(checksum_asset.name, "Proton-6.20-GE-1.sha512sum");
154        assert_eq!(checksum_asset.content_type, APPLICATION_OCTET_STREAM);
155        assert_eq!(checksum_asset.browser_download_url, "octet");
156    }
157
158    #[test]
159    fn get_checksum_asset_with_binary_octet_stream() {
160        let tag = String::from("6.20-GE-1");
161        let assets = vec![
162            GeAsset::new("Proton-6.20-GE-1.tar.gz", APPLICATION_GZIP, "gzip"),
163            GeAsset::new("Proton-6.20-GE-1.sha512sum", BINARY_OCTET_STREAM, "octet"),
164        ];
165        let release = GeRelease::new(tag, assets);
166
167        let checksum_asset = release.checksum_asset();
168        assert_eq!(checksum_asset.name, "Proton-6.20-GE-1.sha512sum");
169        assert_eq!(checksum_asset.content_type, BINARY_OCTET_STREAM);
170        assert_eq!(checksum_asset.browser_download_url, "octet");
171    }
172
173    #[test]
174    fn get_archive_asset() {
175        let tag = String::from("6.20-GE-1");
176        let assets = vec![
177            GeAsset::new("Proton-6.20-GE-1.tar.gz", APPLICATION_GZIP, "gzip"),
178            GeAsset::new("Proton-6.20-GE-1.sha512sum", APPLICATION_OCTET_STREAM, "octet"),
179        ];
180        let release = GeRelease::new(tag, assets);
181
182        let gzip_asset = release.tar_asset();
183        assert_eq!(gzip_asset.name, "Proton-6.20-GE-1.tar.gz");
184        assert_eq!(gzip_asset.content_type, APPLICATION_GZIP);
185        assert_eq!(gzip_asset.browser_download_url, "gzip");
186    }
187}