1+ use crate :: errors:: { Error , Result } ;
12use crate :: htmlparser;
23
3- use super :: errors:: ErrorChain ;
44use html5ever:: tendril:: TendrilSink ;
55use html5ever:: { self , tree_builder:: TreeBuilderOpts , ParseOpts } ;
66use markup5ever_rcdom:: { Node , NodeData , RcDom } ;
77use regex:: Regex ;
88use std:: fs:: { self , File } ;
99use std:: io:: { self , BufRead } ;
1010use std:: path:: { Path , PathBuf } ;
11- use std:: { error :: Error , rc:: Rc } ;
11+ use std:: rc:: Rc ;
1212use tempfile:: tempfile;
1313use walkdir:: WalkDir ;
1414
@@ -20,7 +20,7 @@ pub struct Addon {
2020
2121pub struct AddonList {
2222 pub addons : Vec < Addon > ,
23- pub errors : Vec < Box < dyn Error > > ,
23+ pub errors : Vec < Error > ,
2424}
2525
2626pub struct Manager {
@@ -39,14 +39,23 @@ impl Manager {
3939 Manager { addon_dir : path }
4040 }
4141
42- pub fn get_addons ( & self ) -> Result < AddonList , Box < dyn Error > > {
42+ pub fn get_addons ( & self ) -> Result < AddonList > {
4343 let mut addon_list = AddonList {
4444 addons : vec ! [ ] ,
4545 errors : vec ! [ ] ,
4646 } ;
4747
48+ if let Err ( err) = fs:: metadata ( & self . addon_dir ) {
49+ return Err ( Error :: CannotOpenAddonDirectory (
50+ self . addon_dir . clone ( ) ,
51+ Box :: new ( err) ,
52+ ) ) ;
53+ }
54+
4855 for entry in WalkDir :: new ( & self . addon_dir ) {
49- let entry_dir = entry?;
56+ let entry_dir = entry. map_err ( |err| {
57+ Error :: CannotOpenAddonDirectory ( self . addon_dir . clone ( ) , Box :: new ( err) )
58+ } ) ?;
5059 let file_path = entry_dir. path ( ) ;
5160
5261 let file_name = entry_dir. file_name ( ) ;
@@ -67,31 +76,25 @@ impl Manager {
6776
6877 match self . read_addon ( addon_dir) {
6978 Ok ( addon) => addon_list. addons . push ( addon) ,
70- Err ( err) => addon_list
71- . errors
72- . push ( format ! ( "while reading addon {:?}: {}" , file_path, err) . into ( ) ) ,
79+ Err ( err) => addon_list. errors . push ( err) ,
7380 }
7481 }
7582
7683 Ok ( addon_list)
7784 }
7885
79- pub fn get_addon ( & self , name : & str ) -> Result < Option < Addon > , Box < dyn Error > > {
80- let addon_list = self . get_addons ( ) . chain_err ( "while getting addons" ) ?;
86+ pub fn get_addon ( & self , name : & str ) -> Result < Option < Addon > > {
87+ let addon_list = self . get_addons ( ) ?;
8188 let found = addon_list. addons . into_iter ( ) . find ( |x| x. name == name) ;
8289 Ok ( found)
8390 }
8491
85- fn read_addon ( & self , path : & Path ) -> Result < Addon , Box < dyn Error > > {
86- let addon_name = path
87- . file_name ( )
88- . ok_or ( simple_error ! ( "cannot get filename" ) ) ?;
89-
90- let addon_name = addon_name
91- . to_str ( )
92- . ok_or ( simple_error ! ( "failed to get addon name" ) ) ?;
92+ fn read_addon ( & self , path : & Path ) -> Result < Addon > {
93+ let addon_name = path. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
9394
94- let file = self . open_addon_metadata_file ( path, addon_name) ?;
95+ let file = self
96+ . open_addon_metadata_file ( path, addon_name)
97+ . map_err ( |err| Error :: CannotReadAddon ( addon_name. to_owned ( ) , Box :: new ( err) ) ) ?;
9598 let re = Regex :: new ( r"## (.*): (.*)" ) . unwrap ( ) ;
9699
97100 let mut addon = Addon {
@@ -124,17 +127,18 @@ impl Manager {
124127 Ok ( addon)
125128 }
126129
127- pub fn delete_addon ( & self , addon : & Addon ) -> Result < ( ) , Box < dyn Error > > {
130+ pub fn delete_addon ( & self , addon : & Addon ) -> Result < ( ) > {
128131 let mut addon_path = self . addon_dir . to_owned ( ) ;
129132 addon_path. push ( & addon. name ) ;
130133
131- fs:: remove_dir_all ( addon_path) . chain_err ( "while removing addon directory" ) ? ;
132-
134+ fs:: remove_dir_all ( addon_path)
135+ . map_err ( |err| Error :: CannotRemoveAddon ( addon . name . to_owned ( ) , Box :: new ( err ) ) ) ? ;
133136 Ok ( ( ) )
134137 }
135138
136- pub fn download_addon ( & self , url : & str ) -> Result < Addon , Box < dyn Error > > {
137- let mut response = reqwest:: blocking:: get ( url) ?;
139+ pub fn download_addon ( & self , url : & str ) -> Result < Addon > {
140+ let mut response = reqwest:: blocking:: get ( url)
141+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
138142
139143 let opts = ParseOpts {
140144 tree_builder : TreeBuilderOpts {
@@ -150,17 +154,25 @@ impl Manager {
150154
151155 let download_link = get_cdn_download_link ( & dom) ;
152156
153- let download_link =
154- download_link. ok_or ( simple_error ! ( "failed to get CDN download link" ) ) ?;
157+ let download_link = download_link. ok_or ( Error :: CannotDownloadAddon (
158+ url. to_owned ( ) ,
159+ "failed to get CDN download link" . into ( ) ,
160+ ) ) ?;
155161
156- let mut response = reqwest:: blocking:: get ( & download_link) ?;
162+ let mut response = reqwest:: blocking:: get ( & download_link)
163+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
157164
158165 let mut tmpfile = tempfile ( ) ?;
159- response. copy_to ( & mut tmpfile) ?;
160- let mut archive = zip:: ZipArchive :: new ( tmpfile) ?;
166+ response
167+ . copy_to ( & mut tmpfile)
168+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
169+ let mut archive = zip:: ZipArchive :: new ( tmpfile)
170+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
161171
162172 for i in 0 ..archive. len ( ) {
163- let mut file = archive. by_index ( i) ?;
173+ let mut file = archive
174+ . by_index ( i)
175+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
164176 let outpath = match file. enclosed_name ( ) {
165177 Some ( path) => {
166178 let mut p = self . addon_dir . clone ( ) ;
@@ -171,36 +183,37 @@ impl Manager {
171183 None => continue ,
172184 } ;
173185
174- if ( & * file. name ( ) ) . ends_with ( '/' ) {
175- fs:: create_dir_all ( & outpath) . unwrap ( ) ;
186+ if ( file. name ( ) ) . ends_with ( '/' ) {
187+ fs:: create_dir_all ( & outpath)
188+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
176189 } else {
177190 if let Some ( p) = outpath. parent ( ) {
178191 if !p. exists ( ) {
179- fs:: create_dir_all ( & p) . unwrap ( ) ;
192+ fs:: create_dir_all ( & p) . map_err ( |err| {
193+ Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) )
194+ } ) ?;
180195 }
181196 }
182- let mut outfile = fs:: File :: create ( & outpath) . unwrap ( ) ;
183- io:: copy ( & mut file, & mut outfile) . unwrap ( ) ;
197+ let mut outfile = fs:: File :: create ( & outpath)
198+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
199+ io:: copy ( & mut file, & mut outfile)
200+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
184201 }
185202 }
186203
187204 let mut addon_path = self . addon_dir . to_owned ( ) ;
188- let addon_name = archive. by_index ( 0 ) ?;
205+ let addon_name = archive
206+ . by_index ( 0 )
207+ . map_err ( |err| Error :: CannotDownloadAddon ( url. to_owned ( ) , Box :: new ( err) ) ) ?;
189208 let addon_name = get_root_dir ( & addon_name. mangled_name ( ) ) ;
190209 addon_path. push ( addon_name) ;
191210
192- let addon = self
193- . read_addon ( & addon_path)
194- . chain_err ( "while reading addon" ) ?;
211+ let addon = self . read_addon ( & addon_path) ?;
195212
196213 Ok ( addon)
197214 }
198215
199- fn open_addon_metadata_file (
200- & self ,
201- path : & Path ,
202- addon_name : & str ,
203- ) -> Result < File , Box < dyn Error > > {
216+ fn open_addon_metadata_file ( & self , path : & Path , addon_name : & str ) -> Result < File > {
204217 let mut filepath = path. to_owned ( ) ;
205218 let mut filepath_lowercase = path. to_owned ( ) ;
206219
@@ -211,12 +224,11 @@ impl Manager {
211224 filepath_lowercase. push ( filename_lowercase) ;
212225
213226 if filepath. exists ( ) {
214- File :: open ( & filepath) . chain_err ( & format ! ( "failed to open {:?}" , & filepath ) )
227+ File :: open ( & filepath) . map_err ( |err| Error :: Other ( Box :: new ( err ) ) )
215228 } else if filepath_lowercase. exists ( ) {
216- File :: open ( & filepath_lowercase)
217- . chain_err ( & format ! ( "failed to open {:?}" , & filepath_lowercase) )
229+ File :: open ( & filepath_lowercase) . map_err ( |err| Error :: Other ( Box :: new ( err) ) )
218230 } else {
219- Err ( "metadata file is missing ". into ( ) )
231+ Err ( Error :: Other ( "missing addon metadata file ". into ( ) ) )
220232 }
221233 }
222234}
@@ -253,16 +265,13 @@ pub fn get_download_url(addon_url: &str) -> Option<String> {
253265 let fns: Vec < fn ( & str ) -> Option < String > > = vec ! [
254266 |url: & str | {
255267 let re = Regex :: new( r"^https://.*esoui\.com/downloads/info(\d+)-(.+)$" ) . unwrap( ) ;
256- re. captures( url) . map( |captures| {
257- captures[ 1 ] . to_owned( )
258- } )
268+ re. captures( url) . map( |captures| captures[ 1 ] . to_owned( ) )
259269 } ,
260270 |url: & str | {
261- let re = Regex :: new( r"^https://.+esoui\.com/downloads/fileinfo\.php\?id=(\d+)$" ) . unwrap( ) ;
262- re. captures( url) . map( |captures| {
263- captures[ 1 ] . to_owned( )
264- } )
265- }
271+ let re =
272+ Regex :: new( r"^https://.+esoui\.com/downloads/fileinfo\.php\?id=(\d+)$" ) . unwrap( ) ;
273+ re. captures( url) . map( |captures| captures[ 1 ] . to_owned( ) )
274+ } ,
266275 ] ;
267276
268277 for f in fns {
0 commit comments