use crate::client;
use std::sync::Arc;
use std::time::Duration;
use crate::{DEFAULT_API_VERSION, DEFAULT_CONNECT_TIMEOUT_SECS, DEFAULT_REQUEST_TIMEOUT_SECS};
#[derive(Clone)]
pub struct Client {
pub(crate) auth_client: Arc<client::Client>,
pub(crate) api_version: String,
pub(crate) connect_timeout: Duration,
pub(crate) request_timeout: Duration,
pub(crate) http_cache: Arc<crate::http::HttpClientCache>,
}
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[error("Failed to build HTTP client.")]
HttpClient {
#[source]
source: reqwest::Error,
},
}
pub struct ClientBuilder {
auth_client: client::Client,
api_version: Option<String>,
connect_timeout: Option<Duration>,
request_timeout: Option<Duration>,
}
impl ClientBuilder {
pub fn new(auth_client: client::Client) -> Self {
Self {
auth_client,
api_version: None,
connect_timeout: None,
request_timeout: None,
}
}
pub fn api_version(mut self, version: impl Into<String>) -> Self {
self.api_version = Some(version.into());
self
}
pub fn connect_timeout(mut self, timeout: Duration) -> Self {
self.connect_timeout = Some(timeout);
self
}
pub fn request_timeout(mut self, timeout: Duration) -> Self {
self.request_timeout = Some(timeout);
self
}
pub fn build(self) -> Result<Client, Error> {
Ok(Client {
auth_client: Arc::new(self.auth_client),
api_version: self
.api_version
.unwrap_or_else(|| DEFAULT_API_VERSION.to_string()),
connect_timeout: self
.connect_timeout
.unwrap_or_else(|| Duration::from_secs(DEFAULT_CONNECT_TIMEOUT_SECS)),
request_timeout: self
.request_timeout
.unwrap_or_else(|| Duration::from_secs(DEFAULT_REQUEST_TIMEOUT_SECS)),
http_cache: Arc::new(crate::http::HttpClientCache::new()),
})
}
}
impl Client {
pub fn auth_client(&self) -> &Arc<client::Client> {
&self.auth_client
}
pub fn api_version(&self) -> &str {
&self.api_version
}
pub(crate) fn base_url(&self) -> Result<String, client::Error> {
let instance_url = self
.auth_client
.instance_url
.as_ref()
.ok_or(client::Error::NotConnected)?;
Ok(format!(
"{}/services/data/v{}",
instance_url, self.api_version
))
}
pub(crate) fn connect_timeout(&self) -> Duration {
self.connect_timeout
}
pub(crate) fn request_timeout(&self) -> Duration {
self.request_timeout
}
pub(crate) async fn get_http_client(&self) -> Result<reqwest::Client, crate::http::Error> {
self.http_cache
.get(
self.auth_client.as_ref(),
self.connect_timeout(),
self.request_timeout(),
)
.await
}
pub fn sobject(&self) -> &Self {
self
}
pub fn composite(&self) -> &Self {
self
}
}