koios_sdk/client/
config.rsuse crate::network::Network;
use governor::Quota;
use std::time::Duration;
#[derive(Debug, Clone)]
pub struct AuthConfig {
pub token: String,
pub expiry: Option<chrono::DateTime<chrono::Utc>>,
}
impl AuthConfig {
pub fn new(token: String) -> Self {
Self {
token,
expiry: None,
}
}
pub fn with_expiry(token: String, expiry: chrono::DateTime<chrono::Utc>) -> Self {
Self {
token,
expiry: Some(expiry),
}
}
pub fn is_valid(&self) -> bool {
match self.expiry {
Some(expiry) => chrono::Utc::now() < expiry,
None => true,
}
}
}
#[derive(Debug, Clone)]
pub struct Config {
pub network: Network,
pub custom_url: Option<String>,
pub auth: Option<AuthConfig>,
pub timeout: Duration,
pub rate_limit: Quota,
}
impl Config {
pub fn new(
network: Network,
custom_url: Option<String>,
auth: Option<AuthConfig>,
timeout: Duration,
rate_limit: Quota,
) -> Self {
Self {
network,
custom_url,
auth,
timeout,
rate_limit,
}
}
pub fn base_url(&self) -> String {
self.custom_url
.clone()
.unwrap_or_else(|| self.network.base_url().to_string())
}
pub fn with_auth(mut self, token: String) -> Self {
self.auth = Some(AuthConfig::new(token));
self
}
pub fn with_auth_expiry(
mut self,
token: String,
expiry: chrono::DateTime<chrono::Utc>,
) -> Self {
self.auth = Some(AuthConfig::with_expiry(token, expiry));
self
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn with_rate_limit(mut self, rate_limit: Quota) -> Self {
self.rate_limit = rate_limit;
self
}
}
impl Default for Config {
fn default() -> Self {
Self {
network: Network::default(),
custom_url: None,
auth: None,
timeout: Duration::from_secs(30),
rate_limit: Quota::per_second(100u32.try_into().unwrap()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::Utc;
use std::time::Duration;
#[test]
fn test_default_config() {
let config = Config::default();
assert_eq!(config.network, Network::Mainnet);
assert!(config.custom_url.is_none());
assert!(config.auth.is_none());
assert_eq!(config.timeout, Duration::from_secs(30));
}
#[test]
fn test_config_builder_pattern() {
let config = Config::default()
.with_auth("test-token".to_string())
.with_timeout(Duration::from_secs(60))
.with_rate_limit(Quota::per_second(50u32.try_into().unwrap()));
assert!(config.auth.is_some());
assert_eq!(config.timeout, Duration::from_secs(60));
}
#[test]
fn test_auth_config_validation() {
let auth = AuthConfig::new("test-token".to_string());
assert!(auth.is_valid());
let future = Utc::now() + chrono::Duration::hours(1);
let auth = AuthConfig::with_expiry("test-token".to_string(), future);
assert!(auth.is_valid());
let past = Utc::now() - chrono::Duration::hours(1);
let auth = AuthConfig::with_expiry("test-token".to_string(), past);
assert!(!auth.is_valid());
}
#[test]
fn test_config_base_url() {
let config = Config::default();
assert_eq!(config.base_url(), Network::Mainnet.base_url());
let custom_url = "https://custom.api.com".to_string();
let config = Config::new(
Network::Mainnet,
Some(custom_url.clone()),
None,
Duration::from_secs(30),
Quota::per_second(100u32.try_into().unwrap()),
);
assert_eq!(config.base_url(), custom_url);
let config = Config::new(
Network::Preprod,
None,
None,
Duration::from_secs(30),
Quota::per_second(100u32.try_into().unwrap()),
);
assert_eq!(config.base_url(), Network::Preprod.base_url());
}
#[test]
fn test_config_with_auth_expiry() {
let expiry = Utc::now() + chrono::Duration::hours(1);
let config = Config::default().with_auth_expiry("test-token".to_string(), expiry);
assert!(config.auth.is_some());
let auth = config.auth.unwrap();
assert_eq!(auth.token, "test-token");
assert!(auth.expiry.is_some());
assert!(auth.is_valid());
}
}