contentstack_api_client_rs/client/config.rs
1use std::time::Duration;
2
3/// Represents the geographical regions supported by the Contentstack API.
4#[derive(Clone, Debug, PartialEq)]
5pub enum Region {
6 AwsNa,
7 AwsEu,
8 AwsAu,
9 AzureNa,
10 AzureEu,
11 GcpNa,
12 GcpEu,
13}
14
15/// The type of client being initialized.
16#[derive(Clone, Debug, PartialEq)]
17pub enum ClientType {
18 /// Content Delivery API (CDN).
19 Delivery,
20 /// Content Management API.
21 Management,
22}
23
24impl Region {
25 /// Returns the Delivery API (CDN) base URL for the current region.
26 pub fn delivery_base_url(&self) -> &'static str {
27 match &self {
28 Region::AwsNa => "https://cdn.contentstack.io",
29 Region::AwsEu => "https://eu-cdn.contentstack.com",
30 Region::AwsAu => "https://au-cdn.contentstack.com",
31 Region::AzureNa => "https://azure-na-cdn.contentstack.com",
32 Region::AzureEu => "https://azure-eu-cdn.contentstack.com",
33 Region::GcpNa => "https://gcp-na-cdn.contentstack.com",
34 Region::GcpEu => "https://gcp-eu-cdn.contentstack.com",
35 }
36 }
37
38 /// Returns the Management API base URL for the current region.
39 pub fn management_base_url(&self) -> &'static str {
40 match &self {
41 Region::AwsNa => "https://api.contentstack.io",
42 Region::AwsEu => "https://eu-api.contentstack.com",
43 Region::AwsAu => "https://au-api.contentstack.com",
44 Region::AzureNa => "https://azure-na-api.contentstack.com",
45 Region::AzureEu => "https://azure-eu-api.contentstack.com",
46 Region::GcpNa => "https://gcp-na-api.contentstack.com",
47 Region::GcpEu => "https://gcp-eu-api.contentstack.com",
48 }
49 }
50}
51
52/// Finalized configuration used by Contentstack clients.
53///
54/// This struct is typically constructed using [`ClientConfig::delivery`] or
55/// [`ClientConfig::management`].
56#[derive(Clone, Debug)]
57pub struct ClientConfig {
58 /// The base URL used for API requests.
59 pub base_url: String,
60 /// Your Contentstack stack API key.
61 pub api_key: String,
62 /// The token used for Management API authentication.
63 pub management_token: String,
64 /// The token used for Delivery API authentication.
65 pub delivery_token: String,
66 /// The publishing environment (e.g., "production"). Only used by the Delivery API.
67 pub environment: Option<String>,
68 /// The maximum duration to wait for a request to complete.
69 pub timeout: Duration,
70 /// The maximum number of concurrent connections allowed in the pool.
71 pub max_connections: usize,
72 /// The geographical region for the API.
73 pub region: Region,
74}
75
76/// Configuration options for initializing a `ClientConfig`.
77///
78/// Provides overrides for the default API endpoints, connection settings, and timeouts.
79///
80/// # Examples
81///
82/// ```
83/// use std::time::Duration;
84/// use contentstack_api_client_rs::{ClientOptions, Region};
85///
86/// let opts = ClientOptions {
87/// base_url: Some("https://custom-cdn.contentstack.com".to_string()),
88/// timeout: Some(Duration::from_secs(60)),
89/// max_connections: Some(100),
90/// region: Some(Region::AwsEu),
91/// };
92/// ```
93#[derive(Default, Clone, Debug)]
94pub struct ClientOptions {
95 /// Custom base URL for the API requests. If not provided, defaults to the region's URL.
96 pub base_url: Option<String>,
97 /// The maximum duration to wait for a request to complete. Defaults to 30 seconds.
98 pub timeout: Option<Duration>,
99 /// The maximum number of concurrent connections allowed. Defaults to 50.
100 pub max_connections: Option<usize>,
101 /// The geographical region for the Contentstack API. Defaults to AWS North America.
102 pub region: Option<Region>,
103}
104
105impl ClientOptions {
106 /// Returns the default configuration options for the given client type.
107 ///
108 /// The defaults are configured to use the AWS North America region,
109 /// a 30-second timeout, and a maximum of 50 concurrent connections.
110 ///
111 /// # Arguments
112 ///
113 /// * `client_type` - The type of client (Delivery or Management).
114 ///
115 /// # Examples
116 ///
117 /// ```
118 /// use contentstack_api_client_rs::client::config::{ClientOptions, ClientType};
119 ///
120 /// let defaults = ClientOptions::get_defaults(ClientType::Delivery);
121 /// assert_eq!(defaults.max_connections, Some(50));
122 /// ```
123 pub fn get_defaults(client_type: ClientType) -> ClientOptions {
124 let timeout: Duration = Duration::from_secs(30);
125 let max_connections = 50;
126
127 let base_url = match client_type {
128 ClientType::Delivery => Region::AwsNa.delivery_base_url(),
129 ClientType::Management => Region::AwsNa.management_base_url(),
130 };
131
132 ClientOptions {
133 base_url: Some(base_url.into()),
134 timeout: Some(timeout),
135 max_connections: Some(max_connections),
136 region: Some(Region::AwsNa),
137 }
138 }
139}
140
141impl ClientConfig {
142 /// Builds a `ClientConfig` configured for the Contentstack Delivery API.
143 ///
144 /// Initializes a configuration object using the provided API key, delivery token,
145 /// and environment. If `opts` is `None`, default settings are applied (AWS NA region,
146 /// 30-second timeout, 50 max connections).
147 ///
148 /// # Arguments
149 ///
150 /// * `api_key` - Your stack's API key
151 /// * `delivery_token` - Your stack's delivery token (read-only)
152 /// * `environment` - The name of the publishing environment
153 /// * `opts` - Optional configuration overrides (`ClientOptions`)
154 ///
155 /// # Examples
156 ///
157 /// ```
158 /// use contentstack_api_client_rs::client::config::ClientConfig;
159 ///
160 /// let config = ClientConfig::delivery("api_key", "delivery_token", "production", None);
161 /// assert_eq!(config.environment.as_deref(), Some("production"));
162 /// ```
163 pub fn delivery(
164 api_key: &str,
165 delivery_token: &str,
166 environment: &str,
167 opts: Option<ClientOptions>,
168 ) -> Self {
169 let defaults = ClientOptions::get_defaults(ClientType::Delivery);
170 let defaults = if let Some(config) = opts {
171 ClientOptions {
172 base_url: config.base_url.or(defaults.base_url),
173 timeout: config.timeout.or(defaults.timeout),
174 max_connections: config.max_connections.or(defaults.max_connections),
175 region: config.region.or(defaults.region),
176 }
177 } else {
178 defaults
179 };
180
181 Self {
182 base_url: defaults.base_url.expect("Base Url not provided"),
183 api_key: api_key.into(),
184 delivery_token: delivery_token.into(),
185 management_token: String::new(),
186 environment: Some(environment.into()),
187 timeout: defaults.timeout.unwrap_or(Duration::from_secs(30)),
188 max_connections: defaults.max_connections.unwrap_or(50),
189 region: defaults.region.expect("Region not provided"),
190 }
191 }
192
193 /// Builds a [`ClientConfig`] for the Management API.
194 ///
195 /// Defaults to AWS NA region (`https://api.contentstack.io`) if no
196 /// `base_url` or `region` override is provided. Management API requests
197 /// do not use an environment, so that field is left empty.
198 ///
199 /// # Arguments
200 ///
201 /// * `api_key` - Your stack's API key
202 /// * `management_token` - Stack management token
203 /// * `opts` - Optional configuration overrides (region, timeout, max connections)
204 pub fn management(api_key: &str, management_token: &str, opts: Option<ClientOptions>) -> Self {
205 let defaults = ClientOptions::get_defaults(ClientType::Management);
206
207 let defaults = if let Some(config) = opts {
208 ClientOptions {
209 base_url: config.base_url.or(defaults.base_url),
210 timeout: config.timeout.or(defaults.timeout),
211 max_connections: config.max_connections.or(defaults.max_connections),
212 region: config.region.or(defaults.region),
213 }
214 } else {
215 defaults
216 };
217
218 Self {
219 base_url: defaults.base_url.expect("Base Url not provided"),
220 api_key: api_key.into(),
221 delivery_token: String::new(),
222 management_token: management_token.into(),
223 environment: None,
224 timeout: defaults.timeout.unwrap_or(Duration::from_secs(30)),
225 max_connections: defaults.max_connections.unwrap_or(50),
226 region: defaults.region.expect("Region not provided"),
227 }
228 }
229}