package Ġcom . example . mobile at tester . data . network Ċ Ċ import Ġandroid . util . Log Ċ import Ġkotlinx . coroutines . delay Ċ import Ġjava . io . IOException Ċ Ċ enum Ġclass ĠStatus Ġ{ ĊĠĠĠ ĠSUCCESS , ĠERROR , ĠLO ADING , ĠID LE Ċ } ĊĊ Ċ data Ġclass ĠResponse < out ĠT >( val Ġstatus : ĠStatus , Ġval Ġdata : ĠT ? Ġ= Ġnull , Ġval Ġmessage : ĠString ? Ġ= Ġnull ) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġ< T > Ġsuccess ( data : ĠT ): ĠResponse < T > Ġ= ĠResponse ( status Ġ= ĠStatus . SUCCESS , Ġdata Ġ= Ġdata ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġ< T > Ġerror ( data : ĠT ? Ġ= Ġnull , Ġmessage : ĠString ): ĠResponse < T > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResponse ( status Ġ= ĠStatus . ERROR , Ġdata Ġ= Ġdata , Ġmessage Ġ= Ġmessage ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġ< T > Ġloading ( data : ĠT ? Ġ= Ġnull ): ĠResponse < T > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResponse ( status Ġ= ĠStatus . LOADING , Ġdata Ġ= Ġdata ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġ< T > Ġidle (): ĠResponse < T > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResponse ( status Ġ= ĠStatus . IDLE ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠRet ries Ġa Ġgiven Ġblock Ġx Ġtimes Ġwith Ġincreasing Ġdelay Ġbetween Ġretries . Ġ( 5 Ġby Ġdefault ) Ċ Ġ* Ġ@ throws ĠException ĠIf Ġthe Ġblock Ġfails Ġx Ġtimes Ċ Ġ*/ Ċ suspend Ġfun Ġ< T > Ġretry IO ( ĊĠĠĠ Ġtimes : ĠInt Ġ= Ġ 5 , ĊĠĠĠ Ġinitial Delay : ĠLong Ġ= Ġ 1 0 0 , Ġ// ĠDelay Ġafter Ġfirst Ġfail ĊĠĠĠ Ġmax Delay : ĠLong Ġ= Ġ 1 0 0 0 , ĊĠĠĠ Ġfactor : ĠDouble Ġ= Ġ 2 . 0 , ĊĠĠĠ Ġblock : Ġsuspend Ġ() Ġ-> ĠT , Ċ ): ĠT ? Ġ{ ĊĠĠĠ Ġvar Ġcurrent Delay Ġ= Ġinitial Delay ĊĊĠĠĠ Ġrepeat ( times ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġblock () ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( current Delay ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Delay Ġ= Ġ( current Delay Ġ* Ġfactor ). to Long (). coerce At Most ( max Delay ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġthrow ĠException (" Operation Ġ$ block Ġfailed Ġ$ times .") Ċ }