use std::time::Duration;
#[derive(Debug, Clone)]
pub struct ClientConfig {
pub base_url: String,
pub websocket_path: Option<String>,
pub performance: PerformanceConfig,
pub auth: Option<AuthConfig>,
pub user_agent: String,
pub default_timeout: Duration,
pub verify_tls: bool,
}
impl Default for ClientConfig {
fn default() -> Self {
Self {
base_url: "http://localhost:3000".to_string(),
websocket_path: None,
performance: PerformanceConfig::default(),
auth: None,
user_agent: format!("zeal-rust-sdk/{}", crate::VERSION),
default_timeout: Duration::from_secs(30),
verify_tls: true,
}
}
}
#[derive(Debug, Clone)]
pub struct PerformanceConfig {
pub max_connections_per_host: usize,
pub connection_timeout: Duration,
pub request_timeout: Duration,
pub tcp_keepalive: Option<Duration>,
pub http2_prior_knowledge: bool,
pub connection_pooling: bool,
pub max_idle_connections: usize,
pub idle_timeout: Duration,
pub compression: bool,
pub ws_ping_interval: Duration,
pub ws_pong_timeout: Duration,
pub ws_max_message_size: usize,
pub ws_max_frame_size: usize,
pub stream_buffer_size: usize,
pub trace_batch_size: usize,
pub trace_batch_timeout: Duration,
}
impl Default for PerformanceConfig {
fn default() -> Self {
Self {
max_connections_per_host: 50,
connection_timeout: Duration::from_secs(10),
request_timeout: Duration::from_secs(30),
tcp_keepalive: Some(Duration::from_secs(60)),
http2_prior_knowledge: true,
connection_pooling: true,
max_idle_connections: 10,
idle_timeout: Duration::from_secs(90),
compression: true,
ws_ping_interval: Duration::from_secs(30),
ws_pong_timeout: Duration::from_secs(10),
ws_max_message_size: 64 * 1024 * 1024, ws_max_frame_size: 16 * 1024 * 1024, stream_buffer_size: 8192,
trace_batch_size: 1000,
trace_batch_timeout: Duration::from_millis(100),
}
}
}
#[derive(Debug, Clone)]
pub struct AuthConfig {
pub bearer_token: String,
}
impl AuthConfig {
pub fn new(token: String) -> Self {
Self {
bearer_token: token,
}
}
pub fn with_bearer_token(token: String) -> Self {
Self::new(token)
}
}
#[derive(Debug, Clone)]
pub struct RetryConfig {
pub max_attempts: usize,
pub initial_delay: Duration,
pub max_delay: Duration,
pub backoff_multiplier: f64,
pub jitter_factor: f64,
pub retryable_status_codes: Vec<u16>,
}
impl Default for RetryConfig {
fn default() -> Self {
Self {
max_attempts: 3,
initial_delay: Duration::from_millis(100),
max_delay: Duration::from_secs(30),
backoff_multiplier: 2.0,
jitter_factor: 0.1,
retryable_status_codes: vec![408, 429, 500, 502, 503, 504],
}
}
}
#[derive(Debug, Clone)]
pub struct WebSocketConfig {
pub connection_timeout: Duration,
pub ping_interval: Duration,
pub pong_timeout: Duration,
pub max_message_size: usize,
pub max_frame_size: usize,
pub max_reconnect_attempts: usize,
pub reconnect_delay: Duration,
pub max_reconnect_delay: Duration,
pub compression: bool,
}
impl Default for WebSocketConfig {
fn default() -> Self {
Self {
connection_timeout: Duration::from_secs(10),
ping_interval: Duration::from_secs(30),
pong_timeout: Duration::from_secs(10),
max_message_size: 64 * 1024 * 1024, max_frame_size: 16 * 1024 * 1024, max_reconnect_attempts: 5,
reconnect_delay: Duration::from_millis(500),
max_reconnect_delay: Duration::from_secs(30),
compression: true,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_client_config_default() {
let config = ClientConfig::default();
assert_eq!(config.base_url, "http://localhost:3000");
assert_eq!(config.default_timeout, Duration::from_secs(30));
assert!(config.verify_tls);
}
#[test]
fn test_performance_config_default() {
let config = PerformanceConfig::default();
assert_eq!(config.max_connections_per_host, 50);
assert_eq!(config.connection_timeout, Duration::from_secs(10));
assert!(config.http2_prior_knowledge);
}
#[test]
fn test_auth_config_new() {
let auth = AuthConfig::new("test-token".to_string());
assert_eq!(auth.bearer_token, "test-token");
}
#[test]
fn test_auth_config_with_bearer_token() {
let auth = AuthConfig::with_bearer_token("test-token".to_string());
assert_eq!(auth.bearer_token, "test-token");
}
}