1111
1212//! Esplora by way of `reqwest` HTTP client.
1313
14- use async_std:: task;
1514use std:: collections:: HashMap ;
15+ use std:: marker:: PhantomData ;
1616use std:: str:: FromStr ;
1717
1818use bitcoin:: consensus:: { deserialize, serialize, Decodable , Encodable } ;
@@ -35,16 +35,19 @@ use crate::{
3535} ;
3636
3737#[ derive( Debug , Clone ) ]
38- pub struct AsyncClient {
38+ pub struct AsyncClient < S = DefaultSleeper > {
3939 /// The URL of the Esplora Server.
4040 url : String ,
4141 /// The inner [`reqwest::Client`] to make HTTP requests.
4242 client : Client ,
4343 /// Number of times to retry a request
4444 max_retries : usize ,
45+
46+ /// Marker for the type of sleeper used
47+ marker : PhantomData < S > ,
4548}
4649
47- impl AsyncClient {
50+ impl < S : Sleeper > AsyncClient < S > {
4851 /// Build an async client from a builder
4952 pub fn from_builder ( builder : Builder ) -> Result < Self , Error > {
5053 let mut client_builder = Client :: builder ( ) ;
@@ -75,15 +78,16 @@ impl AsyncClient {
7578 url : builder. base_url ,
7679 client : client_builder. build ( ) ?,
7780 max_retries : builder. max_retries ,
81+ marker : PhantomData ,
7882 } )
7983 }
8084
81- /// Build an async client from the base url and [`Client`]
8285 pub fn from_client ( url : String , client : Client ) -> Self {
8386 AsyncClient {
8487 url,
8588 client,
8689 max_retries : crate :: DEFAULT_MAX_RETRIES ,
90+ marker : PhantomData ,
8791 }
8892 }
8993
@@ -460,7 +464,7 @@ impl AsyncClient {
460464 loop {
461465 match self . client . get ( url) . send ( ) . await ? {
462466 resp if attempts < self . max_retries && is_status_retryable ( resp. status ( ) ) => {
463- task :: sleep ( delay) . await ;
467+ S :: sleep ( delay) . await ;
464468 attempts += 1 ;
465469 delay *= 2 ;
466470 }
@@ -473,3 +477,20 @@ impl AsyncClient {
473477fn is_status_retryable ( status : reqwest:: StatusCode ) -> bool {
474478 RETRYABLE_ERROR_CODES . contains ( & status. as_u16 ( ) )
475479}
480+
481+ pub trait Sleeper : ' static {
482+ type Sleep : std:: future:: Future < Output = ( ) > ;
483+ fn sleep ( dur : std:: time:: Duration ) -> Self :: Sleep ;
484+ }
485+
486+ #[ derive( Debug , Clone , Copy ) ]
487+ pub struct DefaultSleeper ;
488+
489+ #[ cfg( any( test, feature = "tokio" ) ) ]
490+ impl Sleeper for DefaultSleeper {
491+ type Sleep = tokio:: time:: Sleep ;
492+
493+ fn sleep ( dur : std:: time:: Duration ) -> Self :: Sleep {
494+ tokio:: time:: sleep ( dur)
495+ }
496+ }
0 commit comments