use std::{path::Path, time::Duration};
use crate::{Error, Result};
pub const DEFAULT_WS_URL: &str = "wss://api.ndax.io:8443/WSGateway/";
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
#[derive(Clone, Debug, Default)]
pub struct NdaxCredentials {
pub api_key: String,
pub api_secret: String,
pub user_id: String,
}
impl NdaxCredentials {
pub fn new(
api_key: impl Into<String>,
api_secret: impl Into<String>,
user_id: impl Into<String>,
) -> Self {
Self {
api_key: api_key.into(),
api_secret: api_secret.into(),
user_id: user_id.into(),
}
}
pub fn from_env() -> Result<Self> {
dotenvy::dotenv().ok();
Self::read_from_env()
}
pub fn from_env_file<P: AsRef<Path>>(path: P) -> Result<Self> {
dotenvy::from_path(path.as_ref())
.map_err(|e| Error::Env(format!("Failed to load env file: {}", e)))?;
Self::read_from_env()
}
fn read_from_env() -> Result<Self> {
let api_key = std::env::var("NDAX_API_KEY")
.map_err(|_| Error::Env("NDAX_API_KEY not set".to_string()))?;
let api_secret = std::env::var("NDAX_API_SECRET")
.map_err(|_| Error::Env("NDAX_API_SECRET not set".to_string()))?;
let user_id = std::env::var("NDAX_USER_ID")
.map_err(|_| Error::Env("NDAX_USER_ID not set".to_string()))?;
Ok(Self {
api_key,
api_secret,
user_id,
})
}
}
#[derive(Clone, Debug)]
pub struct NdaxConfig {
pub credentials: Option<NdaxCredentials>,
pub timeout: Duration,
pub ws_url: String,
}
impl Default for NdaxConfig {
fn default() -> Self {
Self {
credentials: None,
timeout: DEFAULT_TIMEOUT,
ws_url: DEFAULT_WS_URL.to_string(),
}
}
}
impl NdaxConfig {
pub fn builder() -> NdaxConfigBuilder { NdaxConfigBuilder::default() }
}
#[derive(Clone, Debug, Default)]
pub struct NdaxConfigBuilder {
credentials: Option<NdaxCredentials>,
timeout: Option<Duration>,
ws_url: Option<String>,
}
impl NdaxConfigBuilder {
pub fn new() -> Self { Self::default() }
pub fn credentials(mut self, credentials: NdaxCredentials) -> Self {
self.credentials = Some(credentials);
self
}
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn ws_url(mut self, ws_url: impl Into<String>) -> Self {
self.ws_url = Some(ws_url.into());
self
}
pub fn build(self) -> Result<NdaxConfig> {
Ok(NdaxConfig {
credentials: self.credentials,
timeout: self.timeout.unwrap_or(DEFAULT_TIMEOUT),
ws_url: self.ws_url.unwrap_or_else(|| DEFAULT_WS_URL.to_string()),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_credentials_new() {
let creds = NdaxCredentials::new("key", "secret", "123");
assert_eq!(creds.api_key, "key");
assert_eq!(creds.api_secret, "secret");
assert_eq!(creds.user_id, "123");
}
#[test]
fn test_config_default() {
let config = NdaxConfig::default();
assert!(config.credentials.is_none());
assert_eq!(config.timeout, DEFAULT_TIMEOUT);
assert_eq!(config.ws_url, DEFAULT_WS_URL);
}
#[test]
fn test_config_builder() {
let creds = NdaxCredentials::new("key", "secret", "123");
let config = NdaxConfig::builder()
.credentials(creds.clone())
.timeout(Duration::from_secs(60))
.ws_url("wss://custom.url/")
.build()
.unwrap();
assert!(config.credentials.is_some());
let config_creds = config.credentials.unwrap();
assert_eq!(config_creds.api_key, "key");
assert_eq!(config.timeout, Duration::from_secs(60));
assert_eq!(config.ws_url, "wss://custom.url/");
}
#[test]
fn test_config_builder_defaults() {
let config = NdaxConfig::builder().build().unwrap();
assert!(config.credentials.is_none());
assert_eq!(config.timeout, DEFAULT_TIMEOUT);
assert_eq!(config.ws_url, DEFAULT_WS_URL);
}
#[test]
fn test_env_loading_missing_vars() {
std::env::remove_var("NDAX_API_KEY");
std::env::remove_var("NDAX_API_SECRET");
std::env::remove_var("NDAX_USER_ID");
let result = NdaxCredentials::read_from_env();
assert!(result.is_err());
}
#[test]
fn test_env_loading_with_vars() {
std::env::set_var("NDAX_API_KEY", "test_key");
std::env::set_var("NDAX_API_SECRET", "test_secret");
std::env::set_var("NDAX_USER_ID", "test_user");
let result = NdaxCredentials::read_from_env();
assert!(result.is_ok());
let creds = result.unwrap();
assert_eq!(creds.api_key, "test_key");
assert_eq!(creds.api_secret, "test_secret");
assert_eq!(creds.user_id, "test_user");
std::env::remove_var("NDAX_API_KEY");
std::env::remove_var("NDAX_API_SECRET");
std::env::remove_var("NDAX_USER_ID");
}
}