metabase_api_rs/api/
builder.rs

1//! Client builder implementation
2
3use crate::api::client::MetabaseClient;
4use crate::core::error::{Error, Result};
5use crate::transport::HttpClientBuilder;
6use std::time::Duration;
7
8#[cfg(feature = "cache")]
9use crate::cache::CacheConfig;
10
11/// Builder for creating MetabaseClient instances
12#[derive(Debug)]
13pub struct ClientBuilder {
14    base_url: String,
15    timeout: Option<Duration>,
16    user_agent: Option<String>,
17    #[cfg(feature = "cache")]
18    cache_config: Option<CacheConfig>,
19    #[cfg(feature = "cache")]
20    cache_enabled: Option<bool>,
21}
22
23impl ClientBuilder {
24    /// Creates a new ClientBuilder with the specified base URL
25    pub fn new(base_url: impl Into<String>) -> Self {
26        Self {
27            base_url: base_url.into(),
28            timeout: None,
29            user_agent: None,
30            #[cfg(feature = "cache")]
31            cache_config: None,
32            #[cfg(feature = "cache")]
33            cache_enabled: None,
34        }
35    }
36
37    /// Sets the request timeout
38    pub fn timeout(mut self, timeout: Duration) -> Self {
39        self.timeout = Some(timeout);
40        self
41    }
42
43    /// Sets the user agent string
44    pub fn user_agent(mut self, user_agent: impl Into<String>) -> Self {
45        self.user_agent = Some(user_agent.into());
46        self
47    }
48
49    /// Sets the cache configuration
50    #[cfg(feature = "cache")]
51    pub fn cache_config(mut self, config: CacheConfig) -> Self {
52        self.cache_config = Some(config);
53        self
54    }
55
56    /// Enables or disables the cache
57    #[cfg(feature = "cache")]
58    pub fn cache_enabled(mut self, enabled: bool) -> Self {
59        self.cache_enabled = Some(enabled);
60        self
61    }
62
63    /// Disables the cache
64    #[cfg(feature = "cache")]
65    pub fn disable_cache(mut self) -> Self {
66        self.cache_enabled = Some(false);
67        self
68    }
69
70    /// Builds the MetabaseClient
71    pub fn build(self) -> Result<MetabaseClient> {
72        // Validate URL
73        if !self.base_url.starts_with("http://") && !self.base_url.starts_with("https://") {
74            return Err(Error::Config(
75                "Invalid URL: must start with http:// or https://".to_string(),
76            ));
77        }
78
79        // Create HTTP client with custom configuration
80        let mut http_builder = HttpClientBuilder::new(&self.base_url);
81
82        if let Some(timeout) = self.timeout {
83            http_builder = http_builder.timeout(timeout);
84        }
85
86        if let Some(user_agent) = self.user_agent {
87            http_builder = http_builder.user_agent(user_agent);
88        }
89
90        let http_client = http_builder.build()?;
91        let auth_manager = crate::api::auth::AuthManager::new();
92
93        #[cfg(feature = "cache")]
94        let cache = {
95            let mut config = self.cache_config.unwrap_or_default();
96            if let Some(enabled) = self.cache_enabled {
97                config.enabled = enabled;
98            }
99            crate::cache::CacheLayer::new(config)
100        };
101
102        // Create HttpProviderSafe adapter for ServiceManager
103        use crate::service::ServiceManager;
104        use crate::transport::http_provider_safe::{HttpClientAdapter, HttpProviderSafe};
105        use std::sync::Arc;
106
107        let http_provider: Arc<dyn HttpProviderSafe> =
108            Arc::new(HttpClientAdapter::new(http_client));
109        let service_manager = ServiceManager::new(http_provider);
110
111        Ok(MetabaseClient {
112            auth_manager,
113            base_url: self.base_url,
114            service_manager,
115            #[cfg(feature = "cache")]
116            cache,
117        })
118    }
119}