From ae2b5aea987ec0b5c22be89b068f55903df5e268 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 30 May 2023 10:38:19 +0200 Subject: [PATCH] Expose API to use a different HttpClient implementation --- src/lib.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4dc22f6..c1643c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -200,7 +200,22 @@ impl Account { /// The [`AccountCredentials`] type is opaque, but supports deserialization. pub fn from_credentials(credentials: AccountCredentials<'_>) -> Result { Ok(Self { - inner: Arc::new(AccountInner::from_credentials(credentials)?), + inner: Arc::new(AccountInner::from_credentials( + credentials, + Box::::default(), + )?), + }) + } + + /// Restore an existing account from the given credentials and HTTP client + /// + /// The [`AccountCredentials`] type is opaque, but supports deserialization. + pub fn from_credentials_and_http( + credentials: AccountCredentials<'_>, + http: Box, + ) -> Result { + Ok(Self { + inner: Arc::new(AccountInner::from_credentials(credentials, http)?), }) } @@ -210,7 +225,34 @@ impl Account { server_url: &str, external_account: Option<&ExternalAccountKey>, ) -> Result { - let client = Client::new(server_url, Box::new(DefaultClient::default())).await?; + Self::create_inner( + account, + external_account, + Client::new(server_url, Box::::default()).await?, + ) + .await + } + + /// Create a new account with a custom HTTP client + pub async fn create_with_http( + account: &NewAccount<'_>, + server_url: &str, + external_account: Option<&ExternalAccountKey>, + http: Box, + ) -> Result { + Self::create_inner( + account, + external_account, + Client::new(server_url, http).await?, + ) + .await + } + + async fn create_inner( + account: &NewAccount<'_>, + external_account: Option<&ExternalAccountKey>, + client: Client, + ) -> Result { let key = Key::generate()?; let payload = NewAccountPayload { new_account: account, @@ -288,11 +330,14 @@ struct AccountInner { } impl AccountInner { - fn from_credentials(credentials: AccountCredentials<'_>) -> Result { + fn from_credentials( + credentials: AccountCredentials<'_>, + http: Box, + ) -> Result { Ok(Self { key: Key::from_pkcs8_der(BASE64_URL_SAFE_NO_PAD.decode(&credentials.key_pkcs8)?)?, client: Client { - http: Box::new(DefaultClient::default()), + http, urls: credentials.urls.into_owned(), }, id: credentials.id.into_owned(), @@ -567,7 +612,9 @@ impl Default for DefaultClient { } } -trait HttpClient { +/// A HTTP client based on [`hyper::Client`] +pub trait HttpClient { + /// Send the given request and return the response fn request(&self, req: Request) -> ResponseFuture; }