@@ -2,8 +2,8 @@ use crate::mirror::Mirror;
22use crate :: target_configs:: archarm:: ArcharmTarget ;
33use crate :: target_configs:: archlinux:: ArchTarget ;
44use crate :: target_configs:: archlinuxcn:: ArchCNTarget ;
5- use crate :: target_configs:: artix:: ArtixTarget ;
65use crate :: target_configs:: arcolinux:: ArcoLinuxTarget ;
6+ use crate :: target_configs:: artix:: ArtixTarget ;
77use crate :: target_configs:: blackarch:: BlackArchTarget ;
88use crate :: target_configs:: cachyos:: CachyOSTarget ;
99use crate :: target_configs:: chaotic:: ChaoticTarget ;
@@ -14,14 +14,13 @@ use crate::target_configs::openbsd::OpenBSDTarget;
1414use crate :: target_configs:: rebornos:: RebornOSTarget ;
1515use crate :: target_configs:: stdin:: StdinTarget ;
1616// use crate::target_configs::ubuntu::UbuntuTarget;
17- use ambassador:: { delegatable_trait , Delegate } ;
17+ use ambassador:: { Delegate , delegatable_trait } ;
1818use clap:: { Parser , Subcommand } ;
19- use itertools:: Itertools ;
2019use serde:: de:: DeserializeOwned ;
2120use std:: collections:: HashSet ;
2221use std:: fmt;
2322use std:: str:: FromStr ;
24- use std:: sync:: { mpsc, Arc } ;
23+ use std:: sync:: mpsc;
2524use std:: time:: Duration ;
2625use thiserror:: Error ;
2726use tokio:: runtime:: Runtime ;
@@ -56,6 +55,10 @@ pub enum AppError {
5655 HttpError { status : u16 , url : String } ,
5756 #[ error( "no mirrors after filtering" ) ]
5857 NoMirrorsAfterFiltering ,
58+ #[ error( "all speed tests failed" ) ]
59+ SpeedTestsFailed ,
60+ #[ error( "no mirror output produced" ) ]
61+ BlankOutput ,
5962 #[ error( transparent) ]
6063 UrlParseError ( #[ from] url:: ParseError ) ,
6164 #[ error( transparent) ]
@@ -88,7 +91,6 @@ pub trait LogFormatter {
8891pub trait FetchMirrors {
8992 fn fetch_mirrors (
9093 & self ,
91- config : Arc < Config > ,
9294 tx_progress : mpsc:: Sender < String > ,
9395 ) -> Result < Vec < Mirror > , AppError > ;
9496}
@@ -145,6 +147,14 @@ pub enum Target {
145147 RebornOS ( RebornOSTarget ) ,
146148}
147149
150+ fn parse_positive_usize ( s : & str ) -> Result < usize , String > {
151+ let n: usize = s. parse ( ) . map_err ( |e| format ! ( "{e}" ) ) ?;
152+ if n == 0 {
153+ return Err ( "value must be at least 1" . into ( ) ) ;
154+ }
155+ Ok ( n)
156+ }
157+
148158#[ derive( Debug , Parser ) ]
149159#[ command(
150160 name = "rate-mirrors config" ,
@@ -266,7 +276,7 @@ pub struct Config {
266276 pub top_mirrors_number_to_retest : usize ,
267277
268278 /// Max number of mirrors to output
269- #[ arg( env = "RATE_MIRRORS_MAX_MIRRORS_TO_OUTPUT" , long) ]
279+ #[ arg( env = "RATE_MIRRORS_MAX_MIRRORS_TO_OUTPUT" , long, value_parser = parse_positive_usize ) ]
270280 pub max_mirrors_to_output : Option < usize > ,
271281
272282 /// Filename to save the output to in case of success
@@ -285,6 +295,10 @@ pub struct Config {
285295 #[ arg( env = "RATE_MIRRORS_DISABLE_COMMENTS_IN_FILE" , long) ]
286296 pub disable_comments_in_file : bool ,
287297
298+ /// Exit with error instead of outputting untested mirrors when all speed tests fail
299+ #[ arg( env = "RATE_MIRRORS_DISABLE_UNTESTED_FALLBACK" , long) ]
300+ pub disable_untested_fallback : bool ,
301+
288302 /// Pre-parsed set of excluded country codes (lowercase)
289303 #[ arg( skip) ]
290304 pub excluded_countries_set : HashSet < String > ,
@@ -306,34 +320,22 @@ impl Config {
306320 config
307321 }
308322
309- pub fn is_protocol_allowed ( & self , protocol : & Protocol ) -> bool {
310- self . protocols . is_empty ( ) || self . protocols . contains ( protocol)
311- }
312-
313323 pub fn is_country_excluded ( & self , code : & str ) -> bool {
314324 self . excluded_countries_set
315325 . contains ( & code. to_ascii_lowercase ( ) )
316326 }
317327
318328 pub fn is_protocol_allowed_for_url ( & self , url : & Url ) -> bool {
319- self . protocols . is_empty ( )
320- || url
321- . scheme ( )
329+ if self . protocols . is_empty ( ) {
330+ matches ! ( url. scheme( ) , "http" | "https" )
331+ } else {
332+ url. scheme ( )
322333 . parse ( )
323334 . map ( |p| self . protocols . contains ( & p) )
324335 . unwrap_or ( false )
336+ }
325337 }
326338
327- pub fn get_preferred_url < ' a > ( & self , urls : & ' a [ Url ] ) -> Option < & ' a Url > {
328- urls. iter ( )
329- . filter ( |u| self . is_protocol_allowed_for_url ( u) )
330- . sorted_by_key ( |u| match u. scheme ( ) {
331- "https" => 0 ,
332- "http" => 1 ,
333- _ => 2 ,
334- } )
335- . next ( )
336- }
337339}
338340
339341fn convert_reqwest_error ( e : reqwest:: Error , url : & str ) -> AppError {
0 commit comments