@@ -9,22 +9,48 @@ use msfs::network::*;
9
9
use crate :: download:: zip_handler:: ZipFileHandler ;
10
10
use crate :: util:: JsonParser ;
11
11
12
+ pub struct DownloadStatistics {
13
+ pub total_files : usize ,
14
+ pub files_unzipped : usize ,
15
+ pub files_to_unzip : usize ,
16
+ }
17
+
18
+ #[ derive( PartialEq , Eq , Clone ) ]
19
+ pub enum DownloadStatus {
20
+ NoDownload ,
21
+ Downloading ,
22
+ Extracting ,
23
+ Done ,
24
+ Failed ( String ) ,
25
+ }
26
+
12
27
pub struct NavdataDownloader {
13
28
zip_handler : RefCell < Option < ZipFileHandler < Cursor < Vec < u8 > > > > > ,
29
+ status : RefCell < DownloadStatus > ,
14
30
}
15
31
16
32
impl NavdataDownloader {
17
33
pub fn new ( ) -> Self {
18
34
NavdataDownloader {
19
35
zip_handler : RefCell :: new ( None ) ,
36
+ status : RefCell :: new ( DownloadStatus :: NoDownload ) ,
20
37
}
21
38
}
22
39
23
40
pub fn download ( self : & Rc < Self > , args : & [ u8 ] ) {
24
- println ! ( "[WASM] call received" ) ;
41
+ // Set our status to downloading (needs to be done in its own scope so that the borrow_mut is dropped)
42
+ {
43
+ let mut status = self . status . borrow_mut ( ) ;
44
+ * status = DownloadStatus :: Downloading ;
45
+ println ! ( "[WASM] Downloading" ) ;
46
+ }
47
+
25
48
let json_result = JsonParser :: parse ( args) ;
26
49
if json_result. is_err ( ) {
27
- println ! ( "[WASM] json error: {}" , json_result. err( ) . unwrap( ) ) ;
50
+ let mut status = self . status . borrow_mut ( ) ;
51
+ let error = json_result. err ( ) . unwrap ( ) ;
52
+ * status = DownloadStatus :: Failed ( format ! ( "JSON Parsing error from JS: {}" , error) ) ;
53
+ println ! ( "[WASM] Failed: {}" , error) ;
28
54
return ;
29
55
}
30
56
let json = json_result. unwrap ( ) ;
@@ -42,49 +68,84 @@ impl NavdataDownloader {
42
68
43
69
fn request_finished_callback ( & self , request : NetworkRequest , status_code : i32 ) {
44
70
if status_code != 200 {
45
- println ! ( "[WASM] request failed" ) ;
71
+ let mut status = self . status . borrow_mut ( ) ;
72
+ * status = DownloadStatus :: Failed ( format ! (
73
+ "Request failed with code {} and status {}" ,
74
+ request. error_code( ) ,
75
+ status_code
76
+ ) ) ;
46
77
return ;
47
78
}
48
79
let path = PathBuf :: from ( "\\ work/navdata" ) ;
49
80
if let Err ( e) = fs:: create_dir_all ( & path) {
50
- println ! ( "[WASM] directory error: {}" , e) ;
81
+ let mut status = self . status . borrow_mut ( ) ;
82
+ * status = DownloadStatus :: Failed ( format ! ( "Failed to create directory: {}" , e) ) ;
51
83
return ;
52
84
}
53
85
54
- let data = request. data ( ) . unwrap ( ) ;
86
+ let data = request. data ( ) ;
87
+ if data. is_none ( ) {
88
+ let mut status = self . status . borrow_mut ( ) ;
89
+ * status = DownloadStatus :: Failed ( "No data received" . to_string ( ) ) ;
90
+ return ;
91
+ }
92
+ let data = data. unwrap ( ) ;
55
93
let cursor = Cursor :: new ( data) ;
56
94
let zip = zip:: ZipArchive :: new ( cursor) . unwrap ( ) ;
57
95
58
96
let handler = ZipFileHandler :: new ( zip, path) ;
97
+
59
98
let mut zip_handler = self . zip_handler . borrow_mut ( ) ;
60
99
* zip_handler = Some ( handler) ;
61
- }
62
100
63
- /// Returns the number of files left to unzip
64
- pub fn get_files_to_unzip ( & self ) -> usize {
65
- let zip_handler = self . zip_handler . borrow ( ) ;
66
- match zip_handler. as_ref ( ) {
67
- Some ( handler) => handler. zip_file_count - handler. current_file_index ,
68
- None => 0 ,
101
+ // Set our status to extracting (needs to be done in its own scope so that the borrow_mut is dropped)
102
+ {
103
+ let mut status = self . status . borrow_mut ( ) ;
104
+ * status = DownloadStatus :: Extracting ;
105
+ println ! ( "[WASM] Extracting" ) ;
69
106
}
70
107
}
71
108
72
- /// Returns the total number of files in the zip
73
- pub fn get_total_files ( & self ) -> usize {
74
- let zip_handler = self . zip_handler . borrow ( ) ;
75
- match zip_handler. as_ref ( ) {
76
- Some ( handler) => handler. zip_file_count ,
77
- None => 0 ,
78
- }
109
+ pub fn get_download_statistics (
110
+ & self ,
111
+ ) -> Result < DownloadStatistics , Box < dyn std:: error:: Error > > {
112
+ let zip_handler_ref = self . zip_handler . borrow ( ) ; // Borrow and hold onto the reference
113
+ let zip_handler = zip_handler_ref. as_ref ( ) . ok_or ( "No zip handler" ) ?;
114
+
115
+ let total_files = zip_handler. zip_file_count ;
116
+ let files_unzipped = zip_handler. current_file_index ;
117
+ let files_to_unzip = total_files - files_unzipped;
118
+
119
+ Ok ( DownloadStatistics {
120
+ total_files,
121
+ files_unzipped,
122
+ files_to_unzip,
123
+ } )
79
124
}
80
125
81
- /// Returns the number of files that have been unzipped
82
- pub fn get_files_unzipped ( & self ) -> usize {
83
- let zip_handler = self . zip_handler . borrow ( ) ;
84
- match zip_handler. as_ref ( ) {
85
- Some ( handler) => handler. current_file_index ,
86
- None => 0 ,
87
- }
126
+ /// This basically either sets the status to no download, extracting, or done
127
+ pub fn update_and_get_status ( & self ) -> DownloadStatus {
128
+ let mut status = self . status . borrow_mut ( ) ;
129
+ let zip_handler_option = self . zip_handler . borrow ( ) ;
130
+
131
+ // If there is no zip handler, we are not downloading
132
+ * status = match zip_handler_option. as_ref ( ) {
133
+ None => DownloadStatus :: NoDownload ,
134
+ Some ( zip_handler) => {
135
+ // Downloaded all files
136
+ match zip_handler
137
+ . zip_file_count
138
+ . cmp ( & zip_handler. current_file_index )
139
+ {
140
+ std:: cmp:: Ordering :: Equal => DownloadStatus :: Done ,
141
+ std:: cmp:: Ordering :: Greater => DownloadStatus :: Extracting ,
142
+ _ => return status. clone ( ) ,
143
+ }
144
+ }
145
+ } ;
146
+
147
+ // Clone here to return the updated status
148
+ status. clone ( )
88
149
}
89
150
90
151
/// Unzips a batch of files
@@ -97,4 +158,14 @@ impl NavdataDownloader {
97
158
None => false ,
98
159
}
99
160
}
161
+
162
+ pub fn clear_zip_handler ( & self ) {
163
+ // Borrow mutably and set the zip handler to None. We need to do this in its own scope so that the borrow_mut is dropped
164
+ // I really don't like this since update_and_get_status also borrows mutably but I don't know how else to do it/what the best way is
165
+ {
166
+ let mut zip_handler = self . zip_handler . borrow_mut ( ) ;
167
+ * zip_handler = None ;
168
+ }
169
+ self . update_and_get_status ( ) ;
170
+ }
100
171
}
0 commit comments