hivehub_internal_sdk/
config.rs1use crate::error::HiveHubCloudError;
2use std::time::Duration;
3
4#[derive(Debug, Clone)]
6pub struct ClientConfig {
7 pub api_key: String,
9
10 pub base_url: String,
12
13 pub timeout: Duration,
15
16 pub retries: u32,
18
19 pub retry_delay: Duration,
21}
22
23impl ClientConfig {
24 pub fn new(api_key: String, base_url: String) -> Self {
26 Self {
27 api_key,
28 base_url,
29 timeout: Duration::from_secs(30),
30 retries: 3,
31 retry_delay: Duration::from_millis(1000),
32 }
33 }
34
35 pub fn from_env() -> Result<Self, HiveHubCloudError> {
37 let api_key = std::env::var("HIVEHUB_CLOUD_SERVICE_API_KEY").map_err(|_| {
38 HiveHubCloudError::Configuration(
39 "HIVEHUB_CLOUD_SERVICE_API_KEY environment variable not set".to_string(),
40 )
41 })?;
42
43 let base_url = std::env::var("HIVEHUB_CLOUD_BASE_URL")
44 .unwrap_or_else(|_| "http://localhost:12000".to_string());
45
46 let timeout = std::env::var("HIVEHUB_CLOUD_TIMEOUT")
47 .ok()
48 .and_then(|v| v.parse().ok())
49 .unwrap_or(30);
50
51 let retries = std::env::var("HIVEHUB_CLOUD_RETRIES")
52 .ok()
53 .and_then(|v| v.parse().ok())
54 .unwrap_or(3);
55
56 Ok(Self {
57 api_key,
58 base_url,
59 timeout: Duration::from_secs(timeout),
60 retries,
61 retry_delay: Duration::from_millis(1000),
62 })
63 }
64}
65
66impl Default for ClientConfig {
67 fn default() -> Self {
68 Self {
69 api_key: String::new(),
70 base_url: "http://localhost:12000".to_string(),
71 timeout: Duration::from_secs(30),
72 retries: 3,
73 retry_delay: Duration::from_millis(1000),
74 }
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use std::sync::Mutex;
82
83 static ENV_MUTEX: Mutex<()> = Mutex::new(());
85
86 #[test]
87 fn test_config_new() {
88 let config = ClientConfig::new("test_key".to_string(), "http://example.com".to_string());
89 assert_eq!(config.api_key, "test_key");
90 assert_eq!(config.base_url, "http://example.com");
91 assert_eq!(config.timeout, Duration::from_secs(30));
92 assert_eq!(config.retries, 3);
93 assert_eq!(config.retry_delay, Duration::from_millis(1000));
94 }
95
96 #[test]
97 fn test_config_default() {
98 let config = ClientConfig::default();
99 assert_eq!(config.api_key, "");
100 assert_eq!(config.base_url, "http://localhost:12000");
101 assert_eq!(config.timeout, Duration::from_secs(30));
102 assert_eq!(config.retries, 3);
103 assert_eq!(config.retry_delay, Duration::from_millis(1000));
104 }
105
106 #[test]
107 fn test_config_from_env_missing_key() {
108 let _guard = ENV_MUTEX.lock().unwrap();
109 unsafe {
111 std::env::remove_var("HIVEHUB_CLOUD_SERVICE_API_KEY");
112 }
113 let result = ClientConfig::from_env();
114 assert!(result.is_err());
115 match result.unwrap_err() {
116 HiveHubCloudError::Configuration(msg) => {
117 assert!(msg.contains("HIVEHUB_CLOUD_SERVICE_API_KEY"));
118 }
119 _ => panic!("Expected Configuration error"),
120 }
121 }
122
123 #[test]
124 fn test_config_from_env_with_all_vars() {
125 let _guard = ENV_MUTEX.lock().unwrap();
126 unsafe {
128 std::env::set_var("HIVEHUB_CLOUD_SERVICE_API_KEY", "test_api_key_all");
129 std::env::set_var("HIVEHUB_CLOUD_BASE_URL", "http://custom.url");
130 std::env::set_var("HIVEHUB_CLOUD_TIMEOUT", "60");
131 std::env::set_var("HIVEHUB_CLOUD_RETRIES", "5");
132 }
133
134 let config = ClientConfig::from_env().unwrap();
135 assert_eq!(config.api_key, "test_api_key_all");
136 assert_eq!(config.base_url, "http://custom.url");
137 assert_eq!(config.timeout, Duration::from_secs(60));
138 assert_eq!(config.retries, 5);
139
140 unsafe {
142 std::env::remove_var("HIVEHUB_CLOUD_SERVICE_API_KEY");
143 std::env::remove_var("HIVEHUB_CLOUD_BASE_URL");
144 std::env::remove_var("HIVEHUB_CLOUD_TIMEOUT");
145 std::env::remove_var("HIVEHUB_CLOUD_RETRIES");
146 }
147 }
148
149 #[test]
150 fn test_config_from_env_with_defaults() {
151 let _guard = ENV_MUTEX.lock().unwrap();
152 unsafe {
154 std::env::set_var("HIVEHUB_CLOUD_SERVICE_API_KEY", "default_test_key");
155 std::env::remove_var("HIVEHUB_CLOUD_BASE_URL");
156 std::env::remove_var("HIVEHUB_CLOUD_TIMEOUT");
157 std::env::remove_var("HIVEHUB_CLOUD_RETRIES");
158 }
159
160 let config = ClientConfig::from_env().unwrap();
161 assert_eq!(config.api_key, "default_test_key");
162 assert_eq!(config.base_url, "http://localhost:12000");
163 assert_eq!(config.timeout, Duration::from_secs(30));
164 assert_eq!(config.retries, 3);
165
166 unsafe {
168 std::env::remove_var("HIVEHUB_CLOUD_SERVICE_API_KEY");
169 }
170 }
171
172 #[test]
173 fn test_config_from_env_with_invalid_timeout() {
174 let _guard = ENV_MUTEX.lock().unwrap();
175 unsafe {
177 std::env::set_var("HIVEHUB_CLOUD_SERVICE_API_KEY", "test_key_timeout");
178 std::env::set_var("HIVEHUB_CLOUD_TIMEOUT", "invalid");
179 std::env::remove_var("HIVEHUB_CLOUD_BASE_URL");
180 std::env::remove_var("HIVEHUB_CLOUD_RETRIES");
181 }
182
183 let config = ClientConfig::from_env().unwrap();
184 assert_eq!(config.timeout, Duration::from_secs(30));
186
187 unsafe {
189 std::env::remove_var("HIVEHUB_CLOUD_SERVICE_API_KEY");
190 std::env::remove_var("HIVEHUB_CLOUD_TIMEOUT");
191 }
192 }
193
194 #[test]
195 fn test_config_from_env_with_invalid_retries() {
196 let _guard = ENV_MUTEX.lock().unwrap();
197 unsafe {
199 std::env::set_var("HIVEHUB_CLOUD_SERVICE_API_KEY", "test_key_retries");
200 std::env::set_var("HIVEHUB_CLOUD_RETRIES", "not_a_number");
201 std::env::remove_var("HIVEHUB_CLOUD_BASE_URL");
202 std::env::remove_var("HIVEHUB_CLOUD_TIMEOUT");
203 }
204
205 let config = ClientConfig::from_env().unwrap();
206 assert_eq!(config.retries, 3);
208
209 unsafe {
211 std::env::remove_var("HIVEHUB_CLOUD_SERVICE_API_KEY");
212 std::env::remove_var("HIVEHUB_CLOUD_RETRIES");
213 }
214 }
215
216 #[test]
217 fn test_config_clone() {
218 let config = ClientConfig::new("key".to_string(), "url".to_string());
219 let cloned = config.clone();
220 assert_eq!(config.api_key, cloned.api_key);
221 assert_eq!(config.base_url, cloned.base_url);
222 }
223
224 #[test]
225 fn test_config_debug() {
226 let config = ClientConfig::new("key".to_string(), "url".to_string());
227 let debug_str = format!("{config:?}");
228 assert!(debug_str.contains("ClientConfig"));
229 assert!(debug_str.contains("key"));
230 }
231}