koios_sdk/client/
config.rs1use crate::network::Network;
4use governor::Quota;
5use std::time::Duration;
6
7#[derive(Debug, Clone)]
9pub struct AuthConfig {
10 pub token: String,
12 pub expiry: Option<chrono::DateTime<chrono::Utc>>,
14}
15
16impl AuthConfig {
17 pub fn new(token: String) -> Self {
19 Self {
20 token,
21 expiry: None,
22 }
23 }
24
25 pub fn with_expiry(token: String, expiry: chrono::DateTime<chrono::Utc>) -> Self {
27 Self {
28 token,
29 expiry: Some(expiry),
30 }
31 }
32
33 pub fn is_valid(&self) -> bool {
35 match self.expiry {
36 Some(expiry) => chrono::Utc::now() < expiry,
37 None => true,
38 }
39 }
40}
41
42#[derive(Debug, Clone)]
44pub struct Config {
45 pub network: Network,
47 pub custom_url: Option<String>,
49 pub auth: Option<AuthConfig>,
51 pub timeout: Duration,
53 pub rate_limit: Quota,
55}
56
57impl Config {
58 pub fn new(
60 network: Network,
61 custom_url: Option<String>,
62 auth: Option<AuthConfig>,
63 timeout: Duration,
64 rate_limit: Quota,
65 ) -> Self {
66 Self {
67 network,
68 custom_url,
69 auth,
70 timeout,
71 rate_limit,
72 }
73 }
74
75 pub fn base_url(&self) -> String {
77 self.custom_url
78 .clone()
79 .unwrap_or_else(|| self.network.base_url().to_string())
80 }
81
82 pub fn with_auth(mut self, token: String) -> Self {
84 self.auth = Some(AuthConfig::new(token));
85 self
86 }
87
88 pub fn with_auth_expiry(
90 mut self,
91 token: String,
92 expiry: chrono::DateTime<chrono::Utc>,
93 ) -> Self {
94 self.auth = Some(AuthConfig::with_expiry(token, expiry));
95 self
96 }
97
98 pub fn with_timeout(mut self, timeout: Duration) -> Self {
100 self.timeout = timeout;
101 self
102 }
103
104 pub fn with_rate_limit(mut self, rate_limit: Quota) -> Self {
106 self.rate_limit = rate_limit;
107 self
108 }
109}
110
111impl Default for Config {
112 fn default() -> Self {
113 Self {
114 network: Network::default(),
115 custom_url: None,
116 auth: None,
117 timeout: Duration::from_secs(30),
118 rate_limit: Quota::per_second(100u32.try_into().unwrap()),
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126 use chrono::Utc;
127 use std::time::Duration;
128
129 #[test]
130 fn test_default_config() {
131 let config = Config::default();
132 assert_eq!(config.network, Network::Mainnet);
133 assert!(config.custom_url.is_none());
134 assert!(config.auth.is_none());
135 assert_eq!(config.timeout, Duration::from_secs(30));
136 }
137
138 #[test]
139 fn test_config_builder_pattern() {
140 let config = Config::default()
141 .with_auth("test-token".to_string())
142 .with_timeout(Duration::from_secs(60))
143 .with_rate_limit(Quota::per_second(50u32.try_into().unwrap()));
144
145 assert!(config.auth.is_some());
146 assert_eq!(config.timeout, Duration::from_secs(60));
147 }
148
149 #[test]
150 fn test_auth_config_validation() {
151 let auth = AuthConfig::new("test-token".to_string());
153 assert!(auth.is_valid());
154
155 let future = Utc::now() + chrono::Duration::hours(1);
157 let auth = AuthConfig::with_expiry("test-token".to_string(), future);
158 assert!(auth.is_valid());
159
160 let past = Utc::now() - chrono::Duration::hours(1);
162 let auth = AuthConfig::with_expiry("test-token".to_string(), past);
163 assert!(!auth.is_valid());
164 }
165
166 #[test]
167 fn test_config_base_url() {
168 let config = Config::default();
170 assert_eq!(config.base_url(), Network::Mainnet.base_url());
171
172 let custom_url = "https://custom.api.com".to_string();
174 let config = Config::new(
175 Network::Mainnet,
176 Some(custom_url.clone()),
177 None,
178 Duration::from_secs(30),
179 Quota::per_second(100u32.try_into().unwrap()),
180 );
181 assert_eq!(config.base_url(), custom_url);
182
183 let config = Config::new(
185 Network::Preprod,
186 None,
187 None,
188 Duration::from_secs(30),
189 Quota::per_second(100u32.try_into().unwrap()),
190 );
191 assert_eq!(config.base_url(), Network::Preprod.base_url());
192 }
193
194 #[test]
195 fn test_config_with_auth_expiry() {
196 let expiry = Utc::now() + chrono::Duration::hours(1);
197 let config = Config::default().with_auth_expiry("test-token".to_string(), expiry);
198
199 assert!(config.auth.is_some());
200 let auth = config.auth.unwrap();
201 assert_eq!(auth.token, "test-token");
202 assert!(auth.expiry.is_some());
203 assert!(auth.is_valid());
204 }
205}