Skip to main content

deribit_http/config/
base.rs

1//! Base configuration for HTTP client
2
3use crate::config::credentials::ApiCredentials;
4use crate::constants::{DEFAULT_TIMEOUT, MAX_RETRIES, PRODUCTION_BASE_URL, TESTNET_BASE_URL};
5use pretty_simple_display::{DebugPretty, DisplaySimple};
6use serde::{Deserialize, Serialize};
7#[cfg(not(target_arch = "wasm32"))]
8use std::env;
9use std::time::Duration;
10use url::Url;
11
12/// Configuration for the HTTP client
13#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
14pub struct HttpConfig {
15    /// Base URL for API requests
16    pub base_url: Url,
17    /// Request timeout
18    pub timeout: Duration,
19    /// Maximum number of retries
20    pub max_retries: u32,
21    /// User agent string
22    pub user_agent: String,
23    /// Whether to use testnet
24    pub testnet: bool,
25    /// API credentials
26    pub credentials: Option<ApiCredentials>,
27}
28
29impl Default for HttpConfig {
30    #[cfg(not(target_arch = "wasm32"))]
31    fn default() -> Self {
32        let testnet = env::var("DERIBIT_TESTNET")
33            .map(|val| val.to_lowercase() == "true")
34            .unwrap_or(true); // Default to testnet for safety
35
36        let base_url = if testnet {
37            Url::parse(TESTNET_BASE_URL).expect("Invalid testnet URL")
38        } else {
39            Url::parse(PRODUCTION_BASE_URL).expect("Invalid base URL")
40        };
41
42        Self::from_env(base_url, testnet)
43    }
44
45    #[cfg(target_arch = "wasm32")]
46    fn default() -> Self {
47        Self::testnet()
48    }
49}
50
51impl HttpConfig {
52    /// Read shared configuration from environment variables.
53    #[cfg(not(target_arch = "wasm32"))]
54    fn from_env(base_url: Url, testnet: bool) -> Self {
55        dotenv::dotenv().ok();
56        let credentials = ApiCredentials::new().ok();
57
58        let max_retries = env::var("DERIBIT_HTTP_MAX_RETRIES")
59            .map(|val| val.parse::<u32>().unwrap_or(MAX_RETRIES))
60            .unwrap_or(MAX_RETRIES);
61
62        let timeout_u64 = env::var("DERIBIT_HTTP_TIMEOUT")
63            .map(|val| val.parse::<u64>().unwrap_or(DEFAULT_TIMEOUT))
64            .unwrap_or(DEFAULT_TIMEOUT);
65        let timeout = Duration::from_secs(timeout_u64);
66
67        let user_agent = env::var("DERIBIT_HTTP_USER_AGENT")
68            .unwrap_or_else(|_| format!("deribit-http/{}", env!("CARGO_PKG_VERSION")));
69
70        Self {
71            base_url,
72            timeout,
73            max_retries,
74            user_agent,
75            testnet,
76            credentials,
77        }
78    }
79
80    /// Create testnet configuration
81    pub fn testnet() -> Self {
82        Self::create(
83            Url::parse(TESTNET_BASE_URL).expect("Invalid testnet URL"),
84            true,
85        )
86    }
87
88    /// Create production configuration
89    pub fn production() -> Self {
90        Self::create(
91            Url::parse(PRODUCTION_BASE_URL).expect("Invalid production URL"),
92            false,
93        )
94    }
95
96    #[cfg(not(target_arch = "wasm32"))]
97    fn create(base_url: Url, testnet: bool) -> Self {
98        Self::from_env(base_url, testnet)
99    }
100
101    #[cfg(target_arch = "wasm32")]
102    fn create(base_url: Url, testnet: bool) -> Self {
103        Self {
104            base_url,
105            timeout: Duration::from_secs(DEFAULT_TIMEOUT),
106            max_retries: MAX_RETRIES,
107            user_agent: format!("deribit-http/{}", env!("CARGO_PKG_VERSION")),
108            testnet,
109            credentials: None,
110        }
111    }
112
113    /// Set the timeout for requests
114    pub fn with_timeout(mut self, timeout: Duration) -> Self {
115        self.timeout = timeout;
116        self
117    }
118
119    /// Set the maximum number of retries
120    pub fn with_max_retries(mut self, max_retries: u32) -> Self {
121        self.max_retries = max_retries;
122        self
123    }
124
125    /// Set the user agent string
126    pub fn with_user_agent(mut self, user_agent: String) -> Self {
127        self.user_agent = user_agent;
128        self
129    }
130
131    /// Set OAuth2 credentials
132    pub fn with_oauth2(mut self, client_id: String, client_secret: String) -> Self {
133        self.credentials = Some(ApiCredentials {
134            client_id: Some(client_id),
135            client_secret: Some(client_secret),
136        });
137        self
138    }
139
140    /// Check if credentials are configured
141    pub fn has_credentials(&self) -> bool {
142        self.credentials.is_some()
143    }
144
145    /// Get the credentials
146    pub fn credentials(&self) -> Option<&ApiCredentials> {
147        self.credentials.as_ref()
148    }
149}