11#![ expect(
2- clippy:: arithmetic_side_effects,
3- clippy:: as_conversions,
4- clippy:: cast_precision_loss,
52 clippy:: indexing_slicing,
6- clippy:: integer_division_remainder_used,
73 clippy:: missing_asserts_for_indexing,
84 clippy:: wildcard_enum_match_arm
95) ]
@@ -124,6 +120,7 @@ async fn tick_event_listener(
124120) -> Result < ( ) , tokio:: sync:: mpsc:: error:: SendError < Event > > {
125121 let mut tick =
126122 tokio:: time:: interval ( tokio:: time:: Duration :: from_secs_f64 ( 1.0 / FPS ) ) ;
123+ #[ expect( clippy:: integer_division_remainder_used) ]
127124 loop {
128125 tokio:: select! {
129126 biased;
@@ -141,6 +138,7 @@ async fn crossterm_event_listener(
141138 tx : tokio:: sync:: mpsc:: UnboundedSender < Event > ,
142139) -> Result < ( ) , tokio:: sync:: mpsc:: error:: SendError < Event > > {
143140 let mut reader = crossterm:: event:: EventStream :: new ( ) ;
141+ #[ expect( clippy:: integer_division_remainder_used) ]
144142 loop {
145143 tokio:: select! {
146144 biased;
@@ -198,10 +196,13 @@ fn draw(f: &mut Frame, state: &AppState, logger_state: &TuiWidgetState) {
198196 f. render_widget (
199197 Gauge :: default ( )
200198 . block ( Block :: bordered ( ) . title ( "GeoDB download" ) )
201- . ratio ( if state. geodb_total == 0 {
202- 1.0
203- } else {
204- ( state. geodb_downloaded as f64 ) / ( state. geodb_total as f64 )
199+ . ratio ( {
200+ let total = cast:: f64 ( state. geodb_total ) ;
201+ if total == 0.0 {
202+ 1.0
203+ } else {
204+ cast:: f64 ( state. geodb_downloaded ) / total
205+ }
205206 } ) ,
206207 outer_layout[ 1 ] ,
207208 ) ;
@@ -231,63 +232,57 @@ fn draw(f: &mut Frame, state: &AppState, logger_state: &TuiWidgetState) {
231232
232233 f. render_widget (
233234 Gauge :: default ( )
234- . ratio ( if sources_total == 0 {
235- 0.0
236- } else {
237- sources_scraped as f64 / sources_total as f64
235+ . ratio ( {
236+ let total = cast:: f64 ( sources_total) ;
237+ if total == 0.0 {
238+ 1.0
239+ } else {
240+ cast:: f64 ( sources_scraped) / total
241+ }
238242 } )
239243 . block ( Block :: bordered ( ) . title ( "Scraping sources" ) )
240244 . label ( format ! ( "{sources_scraped}/{sources_total}" ) ) ,
241245 layout[ 0 ] ,
242246 ) ;
243247
244- let proxies_checked =
245- state. proxies_checked . get ( proxy_type) . copied ( ) . unwrap_or_default ( ) ;
246- let proxies_working =
247- state. proxies_working . get ( proxy_type) . copied ( ) . unwrap_or_default ( ) ;
248248 let proxies_total =
249249 state. proxies_total . get ( proxy_type) . copied ( ) . unwrap_or_default ( ) ;
250-
250+ let proxies_checked =
251+ state. proxies_checked . get ( proxy_type) . copied ( ) . unwrap_or_default ( ) ;
251252 f. render_widget (
252253 Gauge :: default ( )
253- . ratio ( if proxies_total == 0 {
254- 0.0
255- } else {
256- proxies_checked as f64 / proxies_total as f64
254+ . ratio ( {
255+ let total = cast:: f64 ( proxies_total) ;
256+ if total == 0.0 {
257+ 1.0
258+ } else {
259+ cast:: f64 ( proxies_checked) / total
260+ }
257261 } )
258262 . block ( Block :: bordered ( ) . title ( "Checking proxies" ) )
259263 . label ( format ! ( "{proxies_checked}/{proxies_total}" ) ) ,
260264 layout[ 1 ] ,
261265 ) ;
262266
267+ let working_proxies_block = Block :: bordered ( ) . title ( "Working proxies" ) ;
268+ f. render_widget ( working_proxies_block. clone ( ) , layout[ 2 ] ) ;
269+
270+ let proxies_working =
271+ state. proxies_working . get ( proxy_type) . copied ( ) . unwrap_or_default ( ) ;
263272 f. render_widget (
264- Gauge :: default ( )
265- . ratio ( if proxies_total == 0 {
266- 0.0
267- } else {
268- proxies_checked as f64 / proxies_total as f64
269- } )
270- . block (
271- Block :: bordered ( )
272- . title ( "Working proxies / checked proxies" ) ,
273- )
274- . label ( format ! (
275- "{}/{} ({:.1}%)" ,
276- proxies_working,
277- proxies_checked,
278- if proxies_working != 0 {
279- ( proxies_working as f64 / proxies_checked as f64 )
280- * 100.0_f64
281- } else {
282- 0.0_f64
283- }
284- ) ) ,
285- layout[ 2 ] ,
273+ Line :: from ( format ! (
274+ "{} ({:.1}%)" ,
275+ proxies_working,
276+ ( cast:: f64 ( proxies_working) / cast:: f64 ( proxies_checked) )
277+ * 100.0_f64
278+ ) )
279+ . alignment ( Alignment :: Center ) ,
280+ working_proxies_block. inner ( layout[ 2 ] ) ,
286281 ) ;
287282 }
288283
289284 let done = matches ! ( state. mode, AppMode :: Done ) ;
290- let mut lines = Vec :: with_capacity ( 2 + usize:: from ( done) ) ;
285+ let mut lines = Vec :: with_capacity ( usize:: from ( done) . saturating_add ( 2 ) ) ;
291286 lines. push ( Line :: from ( "Up/PageUp/k - scroll logs up" ) ) ;
292287 lines. push ( Line :: from ( "Down/PageDown/j - scroll logs down" ) ) ;
293288 if done {
@@ -353,22 +348,35 @@ async fn handle_event(
353348 state. geodb_total = bytes. unwrap_or_default ( ) ;
354349 }
355350 AppEvent :: GeoDbDownloaded ( bytes) => {
356- state. geodb_downloaded += bytes;
351+ state. geodb_downloaded =
352+ state. geodb_downloaded . saturating_add ( bytes) ;
357353 }
358354 AppEvent :: SourcesTotal ( proxy_type, amount) => {
359355 state. sources_total . insert ( proxy_type, amount) ;
360356 }
361357 AppEvent :: SourceScraped ( proxy_type) => {
362- * state. sources_scraped . entry ( proxy_type) . or_default ( ) += 1 ;
358+ state
359+ . sources_scraped
360+ . entry ( proxy_type)
361+ . and_modify ( |c| * c = c. saturating_add ( 1 ) )
362+ . or_insert ( 1 ) ;
363363 }
364364 AppEvent :: TotalProxies ( proxy_type, amount) => {
365365 state. proxies_total . insert ( proxy_type, amount) ;
366366 }
367367 AppEvent :: ProxyChecked ( proxy_type) => {
368- * state. proxies_checked . entry ( proxy_type) . or_default ( ) += 1 ;
368+ state
369+ . proxies_checked
370+ . entry ( proxy_type)
371+ . and_modify ( |c| * c = c. saturating_add ( 1 ) )
372+ . or_insert ( 1 ) ;
369373 }
370374 AppEvent :: ProxyWorking ( proxy_type) => {
371- * state. proxies_working . entry ( proxy_type) . or_default ( ) += 1 ;
375+ state
376+ . proxies_working
377+ . entry ( proxy_type)
378+ . and_modify ( |c| * c = c. saturating_add ( 1 ) )
379+ . or_insert ( 1 ) ;
372380 }
373381 AppEvent :: Done => {
374382 state. mode = if is_interactive ( ) . await {
0 commit comments