Wrap Client internals in Arc for cheap cloning
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
use crate::apis::{AlbumsApi, AssetsApi, ServerApi, TimelineApi};
|
||||
use crate::error::{ImmichError, Result};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Configuration for the Immich client
|
||||
@@ -56,13 +57,22 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
/// Client for making requests to the Immich API
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Client {
|
||||
/// Internal client data wrapped in Arc for cheap cloning
|
||||
#[derive(Debug)]
|
||||
struct ClientInner {
|
||||
config: Config,
|
||||
http: reqwest::Client,
|
||||
}
|
||||
|
||||
/// Client for making requests to the Immich API
|
||||
///
|
||||
/// This struct is cheap to clone - it uses an internal Arc to share the underlying
|
||||
/// HTTP client and configuration.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Client {
|
||||
inner: Arc<ClientInner>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Create a new client with the given configuration
|
||||
pub fn new(config: Config) -> Result<Self> {
|
||||
@@ -86,8 +96,10 @@ impl Client {
|
||||
.build()?;
|
||||
|
||||
Ok(Self {
|
||||
inner: Arc::new(ClientInner {
|
||||
config: Config { base_url, ..config },
|
||||
http,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -97,38 +109,46 @@ impl Client {
|
||||
}
|
||||
|
||||
/// Set the API key
|
||||
pub fn with_api_key(mut self, api_key: impl Into<String>) -> Self {
|
||||
self.config.api_key = Some(api_key.into());
|
||||
self
|
||||
pub fn with_api_key(self, api_key: impl Into<String>) -> Self {
|
||||
// We need to create a new ClientInner since we can't modify Arc contents
|
||||
let mut config = self.inner.config.clone();
|
||||
config.api_key = Some(api_key.into());
|
||||
|
||||
Self {
|
||||
inner: Arc::new(ClientInner {
|
||||
config,
|
||||
http: self.inner.http.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the configuration
|
||||
pub fn config(&self) -> &Config {
|
||||
&self.config
|
||||
&self.inner.config
|
||||
}
|
||||
|
||||
/// Get the base URL
|
||||
pub fn base_url(&self) -> &str {
|
||||
&self.config.base_url
|
||||
&self.inner.config.base_url
|
||||
}
|
||||
|
||||
/// Check if the client has an API key configured
|
||||
pub fn has_api_key(&self) -> bool {
|
||||
self.config.api_key.is_some()
|
||||
self.inner.config.api_key.is_some()
|
||||
}
|
||||
|
||||
/// Get the underlying HTTP client
|
||||
pub fn http(&self) -> &reqwest::Client {
|
||||
&self.http
|
||||
&self.inner.http
|
||||
}
|
||||
|
||||
/// Create an authenticated request builder
|
||||
pub fn request(&self, method: reqwest::Method, path: &str) -> reqwest::RequestBuilder {
|
||||
let url = format!("{}/api{}", self.config.base_url, path);
|
||||
let mut builder = self.http.request(method, &url);
|
||||
let url = format!("{}/api{}", self.inner.config.base_url, path);
|
||||
let mut builder = self.inner.http.request(method, &url);
|
||||
|
||||
// Add API key authentication
|
||||
if let Some(ref api_key) = self.config.api_key {
|
||||
if let Some(ref api_key) = self.inner.config.api_key {
|
||||
builder = builder.header("x-api-key", api_key);
|
||||
}
|
||||
|
||||
@@ -137,7 +157,7 @@ impl Client {
|
||||
|
||||
/// Execute a request and handle common error cases
|
||||
pub async fn execute(&self, request: reqwest::Request) -> Result<reqwest::Response> {
|
||||
let response = self.http.execute(request).await?;
|
||||
let response = self.inner.http.execute(request).await?;
|
||||
|
||||
if response.status().is_success() {
|
||||
Ok(response)
|
||||
|
||||
Reference in New Issue
Block a user