koios_sdk/client/
builder.rs1use crate::{
4 client::{AuthConfig, Client, Config},
5 error::Result,
6 network::Network,
7};
8use chrono::{DateTime, Utc};
9use governor::Quota;
10use std::time::Duration;
11
12#[derive(Debug, Default)]
14pub struct ClientBuilder {
15 config: Config,
16}
17
18impl ClientBuilder {
19 pub fn new() -> Self {
21 Self {
22 config: Config::default(),
23 }
24 }
25
26 pub fn network(mut self, network: Network) -> Self {
28 self.config.network = network;
29 self.config.custom_url = None; self
31 }
32
33 pub fn base_url<S: Into<String>>(mut self, url: S) -> Self {
35 self.config.custom_url = Some(url.into());
36 self
37 }
38
39 pub fn auth_token<S: Into<String>>(mut self, token: S) -> Self {
41 self.config.auth = Some(AuthConfig::new(token.into()));
42 self
43 }
44
45 pub fn auth_token_with_expiry<S: Into<String>>(
47 mut self,
48 token: S,
49 expiry: DateTime<Utc>,
50 ) -> Self {
51 self.config.auth = Some(AuthConfig::with_expiry(token.into(), expiry));
52 self
53 }
54
55 pub fn auth(mut self, auth: AuthConfig) -> Self {
57 self.config.auth = Some(auth);
58 self
59 }
60
61 pub fn timeout(mut self, timeout: Duration) -> Self {
63 self.config.timeout = timeout;
64 self
65 }
66
67 pub fn rate_limit(mut self, quota: Quota) -> Self {
69 self.config.rate_limit = quota;
70 self
71 }
72
73 pub fn build(self) -> Result<Client> {
75 Client::with_config(self.config)
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82 use std::time::Duration;
83
84 #[test]
85 fn test_builder_default() {
86 let client = ClientBuilder::new().build().unwrap();
87 assert_eq!(client.base_url(), crate::DEFAULT_API_URL);
88 }
89
90 #[test]
91 fn test_builder_with_auth() {
92 let client = ClientBuilder::new()
93 .auth_token("test-token")
94 .build()
95 .unwrap();
96
97 let rt = tokio::runtime::Runtime::new().unwrap();
99 assert!(rt.block_on(client.has_valid_auth()));
100 assert_eq!(client.auth_token(), Some("test-token".to_string()));
101 }
102
103 #[test]
104 fn test_builder_with_auth_expiry() {
105 let expiry = Utc::now() + chrono::Duration::hours(1);
106 let client = ClientBuilder::new()
107 .auth_token_with_expiry("test-token", expiry)
108 .build()
109 .unwrap();
110
111 let rt = tokio::runtime::Runtime::new().unwrap();
112 assert!(rt.block_on(client.has_valid_auth()));
113 assert_eq!(client.auth_token(), Some("test-token".to_string()));
114 }
115
116 #[test]
117 fn test_builder_with_expired_auth() {
118 let expiry = Utc::now() - chrono::Duration::hours(1);
119 let client = ClientBuilder::new()
120 .auth_token_with_expiry("test-token", expiry)
121 .build()
122 .unwrap();
123
124 let rt = tokio::runtime::Runtime::new().unwrap();
125 assert!(!rt.block_on(client.has_valid_auth()));
126 assert_eq!(client.auth_token(), None);
127 }
128
129 #[test]
130 fn test_builder_with_custom_timeout() {
131 let timeout = Duration::from_secs(60);
132 let client = ClientBuilder::new().timeout(timeout).build().unwrap();
133
134 assert_eq!(client.base_url(), crate::DEFAULT_API_URL);
137 }
138
139 #[test]
140 fn test_builder_with_rate_limit() {
141 let quota = Quota::per_second(50u32.try_into().unwrap());
142 let client = ClientBuilder::new().rate_limit(quota).build().unwrap();
143
144 assert_eq!(client.base_url(), crate::DEFAULT_API_URL);
145 }
146
147 #[test]
148 fn test_builder_with_all_options() {
149 let expiry = Utc::now() + chrono::Duration::hours(1);
150 let client = ClientBuilder::new()
151 .base_url("https://custom.api.com")
152 .auth_token_with_expiry("test-token", expiry)
153 .timeout(Duration::from_secs(60))
154 .rate_limit(Quota::per_second(50u32.try_into().unwrap()))
155 .build()
156 .unwrap();
157
158 assert_eq!(client.base_url(), "https://custom.api.com");
159 assert_eq!(client.auth_token(), Some("test-token".to_string()));
160 }
161
162 #[test]
163 fn test_builder_custom_auth_config() {
164 let auth = AuthConfig::new("test-token".to_string());
165 let client = ClientBuilder::new().auth(auth).build().unwrap();
166
167 assert_eq!(client.auth_token(), Some("test-token".to_string()));
168 }
169
170 #[test]
171 fn test_builder_chaining() {
172 let client = ClientBuilder::new()
173 .base_url("https://custom.api.com")
174 .auth_token("test-token")
175 .timeout(Duration::from_secs(60))
176 .build()
177 .unwrap();
178
179 assert_eq!(client.base_url(), "https://custom.api.com");
180 assert_eq!(client.auth_token(), Some("test-token".to_string()));
181 }
182}