deribit_websocket/
config.rs

1//! Configuration for WebSocket client
2
3use std::env;
4use std::time::Duration;
5use url::Url;
6
7/// WebSocket client configuration
8#[derive(Debug, Clone)]
9pub struct WebSocketConfig {
10    /// WebSocket URL
11    pub ws_url: Url,
12    /// Heartbeat interval
13    pub heartbeat_interval: Duration,
14    /// Maximum reconnection attempts
15    pub max_reconnect_attempts: u32,
16    /// Reconnection delay
17    pub reconnect_delay: Duration,
18    /// Connection timeout
19    pub connection_timeout: Duration,
20    /// Enable logging
21    pub enable_logging: bool,
22    /// Log level
23    pub log_level: String,
24    /// Test mode
25    pub test_mode: bool,
26    /// Client ID for authentication
27    pub client_id: Option<String>,
28    /// Client secret for authentication
29    pub client_secret: Option<String>,
30}
31
32impl Default for WebSocketConfig {
33    fn default() -> Self {
34        // Load environment variables from .env file if it exists
35        {
36            if dotenv::dotenv().is_err() {
37                // .env file not found or error loading, continue with system env vars
38            }
39        }
40
41        let ws_url = env::var("DERIBIT_WS_URL")
42            .unwrap_or_else(|_| "wss://www.deribit.com/ws/api/v2".to_string());
43
44        let heartbeat_interval = env::var("DERIBIT_HEARTBEAT_INTERVAL")
45            .ok()
46            .and_then(|s| s.parse().ok())
47            .map(Duration::from_secs)
48            .unwrap_or_else(|| Duration::from_secs(30));
49
50        let max_reconnect_attempts = env::var("DERIBIT_RECONNECT_ATTEMPTS")
51            .ok()
52            .and_then(|s| s.parse().ok())
53            .unwrap_or(3);
54
55        let reconnect_delay = env::var("DERIBIT_RECONNECT_DELAY")
56            .ok()
57            .and_then(|s| s.parse().ok())
58            .map(Duration::from_secs)
59            .unwrap_or_else(|| Duration::from_secs(5));
60
61        let connection_timeout = env::var("DERIBIT_CONNECTION_TIMEOUT")
62            .ok()
63            .and_then(|s| s.parse().ok())
64            .map(Duration::from_secs)
65            .unwrap_or_else(|| Duration::from_secs(10));
66
67        let enable_logging = env::var("DERIBIT_ENABLE_LOGGING")
68            .ok()
69            .and_then(|s| s.parse().ok())
70            .unwrap_or(true);
71
72        let log_level = env::var("DERIBIT_LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
73
74        let test_mode = env::var("DERIBIT_TEST_MODE")
75            .ok()
76            .and_then(|s| s.parse().ok())
77            .unwrap_or(false);
78
79        let client_id = env::var("DERIBIT_CLIENT_ID").ok();
80        let client_secret = env::var("DERIBIT_CLIENT_SECRET").ok();
81
82        Self {
83            ws_url: Url::parse(&ws_url)
84                .unwrap_or_else(|_| Url::parse("wss://www.deribit.com/ws/api/v2").unwrap()),
85            heartbeat_interval,
86            max_reconnect_attempts,
87            reconnect_delay,
88            connection_timeout,
89            enable_logging,
90            log_level,
91            test_mode,
92            client_id,
93            client_secret,
94        }
95    }
96}
97
98impl WebSocketConfig {
99    /// Create a new configuration with custom URL
100    pub fn with_url(url: &str) -> Result<Self, url::ParseError> {
101        Ok(Self {
102            ws_url: Url::parse(url)?,
103            ..Default::default()
104        })
105    }
106
107    /// Set heartbeat interval
108    pub fn with_heartbeat_interval(mut self, interval: Duration) -> Self {
109        self.heartbeat_interval = interval;
110        self
111    }
112
113    /// Set maximum reconnection attempts
114    pub fn with_max_reconnect_attempts(mut self, attempts: u32) -> Self {
115        self.max_reconnect_attempts = attempts;
116        self
117    }
118
119    /// Set reconnection delay
120    pub fn with_reconnect_delay(mut self, delay: Duration) -> Self {
121        self.reconnect_delay = delay;
122        self
123    }
124
125    /// Set connection timeout
126    pub fn with_connection_timeout(mut self, timeout: Duration) -> Self {
127        self.connection_timeout = timeout;
128        self
129    }
130
131    /// Set client credentials
132    pub fn with_credentials(mut self, client_id: String, client_secret: String) -> Self {
133        self.client_id = Some(client_id);
134        self.client_secret = Some(client_secret);
135        self
136    }
137
138    /// Set client ID
139    pub fn with_client_id(mut self, client_id: String) -> Self {
140        self.client_id = Some(client_id);
141        self
142    }
143
144    /// Set client secret
145    pub fn with_client_secret(mut self, client_secret: String) -> Self {
146        self.client_secret = Some(client_secret);
147        self
148    }
149
150    /// Enable or disable logging
151    pub fn with_logging(mut self, enable: bool) -> Self {
152        self.enable_logging = enable;
153        self
154    }
155
156    /// Set log level
157    pub fn with_log_level(mut self, level: String) -> Self {
158        self.log_level = level;
159        self
160    }
161
162    /// Set test mode
163    pub fn with_test_mode(mut self, test_mode: bool) -> Self {
164        self.test_mode = test_mode;
165        self
166    }
167
168    /// Check if credentials are available
169    pub fn has_credentials(&self) -> bool {
170        self.client_id.is_some() && self.client_secret.is_some()
171    }
172
173    /// Get client credentials as tuple
174    pub fn get_credentials(&self) -> Option<(&str, &str)> {
175        match (&self.client_id, &self.client_secret) {
176            (Some(id), Some(secret)) => Some((id, secret)),
177            _ => None,
178        }
179    }
180}