1use std::env;
6use std::net::SocketAddr;
7
8use crate::error::{Result, SdkError};
9
10#[derive(Debug, Clone)]
12pub struct SdkConfig {
13 pub instance_id: String,
15 pub tenant_id: String,
17 pub server_addr: SocketAddr,
19 pub server_name: String,
21 pub skip_cert_verification: bool,
23 pub connect_timeout_ms: u64,
25 pub request_timeout_ms: u64,
27 pub signal_poll_interval_ms: u64,
29}
30
31impl SdkConfig {
32 pub fn from_env() -> Result<Self> {
46 let instance_id = env::var("RUNTARA_INSTANCE_ID")
47 .map_err(|_| SdkError::Config("RUNTARA_INSTANCE_ID is required".to_string()))?;
48
49 let tenant_id = env::var("RUNTARA_TENANT_ID")
50 .map_err(|_| SdkError::Config("RUNTARA_TENANT_ID is required".to_string()))?;
51
52 let server_addr = env::var("RUNTARA_SERVER_ADDR")
53 .unwrap_or_else(|_| "127.0.0.1:8001".to_string())
54 .parse()
55 .map_err(|e| SdkError::Config(format!("invalid RUNTARA_SERVER_ADDR: {}", e)))?;
56
57 let server_name =
58 env::var("RUNTARA_SERVER_NAME").unwrap_or_else(|_| "localhost".to_string());
59
60 let skip_cert_verification = env::var("RUNTARA_SKIP_CERT_VERIFICATION")
61 .map(|v| v == "true" || v == "1")
62 .unwrap_or(false);
63
64 let connect_timeout_ms = env::var("RUNTARA_CONNECT_TIMEOUT_MS")
65 .ok()
66 .and_then(|v| v.parse().ok())
67 .unwrap_or(10_000);
68
69 let request_timeout_ms = env::var("RUNTARA_REQUEST_TIMEOUT_MS")
70 .ok()
71 .and_then(|v| v.parse().ok())
72 .unwrap_or(30_000);
73
74 let signal_poll_interval_ms = env::var("RUNTARA_SIGNAL_POLL_INTERVAL_MS")
75 .ok()
76 .and_then(|v| v.parse().ok())
77 .unwrap_or(1_000);
78
79 Ok(Self {
80 instance_id,
81 tenant_id,
82 server_addr,
83 server_name,
84 skip_cert_verification,
85 connect_timeout_ms,
86 request_timeout_ms,
87 signal_poll_interval_ms,
88 })
89 }
90
91 pub fn localhost(instance_id: impl Into<String>, tenant_id: impl Into<String>) -> Self {
97 Self {
98 instance_id: instance_id.into(),
99 tenant_id: tenant_id.into(),
100 server_addr: "127.0.0.1:8001".parse().unwrap(),
101 server_name: "localhost".to_string(),
102 skip_cert_verification: true,
103 connect_timeout_ms: 10_000,
104 request_timeout_ms: 30_000,
105 signal_poll_interval_ms: 1_000,
106 }
107 }
108
109 pub fn new(instance_id: impl Into<String>, tenant_id: impl Into<String>) -> Self {
111 Self {
112 instance_id: instance_id.into(),
113 tenant_id: tenant_id.into(),
114 server_addr: "127.0.0.1:8001".parse().unwrap(),
115 server_name: "localhost".to_string(),
116 skip_cert_verification: false,
117 connect_timeout_ms: 10_000,
118 request_timeout_ms: 30_000,
119 signal_poll_interval_ms: 1_000,
120 }
121 }
122
123 pub fn with_server_addr(mut self, addr: SocketAddr) -> Self {
125 self.server_addr = addr;
126 self
127 }
128
129 pub fn with_server_name(mut self, name: impl Into<String>) -> Self {
131 self.server_name = name.into();
132 self
133 }
134
135 pub fn with_skip_cert_verification(mut self, skip: bool) -> Self {
137 self.skip_cert_verification = skip;
138 self
139 }
140
141 pub fn with_signal_poll_interval_ms(mut self, interval_ms: u64) -> Self {
143 self.signal_poll_interval_ms = interval_ms;
144 self
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use super::*;
151
152 #[test]
153 fn test_localhost_config() {
154 let config = SdkConfig::localhost("test-instance", "test-tenant");
155 assert_eq!(config.instance_id, "test-instance");
156 assert_eq!(config.tenant_id, "test-tenant");
157 assert!(config.skip_cert_verification);
158 assert_eq!(config.server_addr, "127.0.0.1:8001".parse().unwrap());
159 }
160
161 #[test]
162 fn test_builder_pattern() {
163 let config = SdkConfig::new("inst", "tenant")
164 .with_server_addr("192.168.1.1:8000".parse().unwrap())
165 .with_skip_cert_verification(true)
166 .with_signal_poll_interval_ms(500);
167
168 assert_eq!(config.server_addr, "192.168.1.1:8000".parse().unwrap());
169 assert!(config.skip_cert_verification);
170 assert_eq!(config.signal_poll_interval_ms, 500);
171 }
172}