use std::collections::HashMap;
#[derive(Clone)]
pub struct TwelvedataAuth {
pub api_key: Option<String>,
}
impl TwelvedataAuth {
pub fn from_env() -> Self {
Self {
api_key: std::env::var("TWELVEDATA_API_KEY").ok(),
}
}
pub fn new(api_key: impl Into<String>) -> Self {
Self {
api_key: Some(api_key.into()),
}
}
pub fn demo() -> Self {
Self {
api_key: Some("demo".to_string()),
}
}
pub fn none() -> Self {
Self { api_key: None }
}
pub fn sign_headers(&self, headers: &mut HashMap<String, String>) {
if let Some(key) = &self.api_key {
headers.insert("Authorization".to_string(), format!("apikey {}", key));
}
}
pub fn add_query_param(&self, params: &mut HashMap<String, String>) {
if let Some(key) = &self.api_key {
params.insert("apikey".to_string(), key.clone());
}
}
pub fn has_credentials(&self) -> bool {
self.api_key.is_some()
}
pub fn is_demo(&self) -> bool {
self.api_key.as_deref() == Some("demo")
}
pub fn masked_key(&self) -> Option<String> {
self.api_key.as_ref().map(|key| {
if key == "demo" {
"demo".to_string()
} else if key.len() > 8 {
format!("{}...{}", &key[..4], &key[key.len() - 4..])
} else {
"****".to_string()
}
})
}
}
impl Default for TwelvedataAuth {
fn default() -> Self {
Self::from_env()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_auth() {
let auth = TwelvedataAuth::new("test_api_key_12345");
assert!(auth.has_credentials());
assert!(!auth.is_demo());
}
#[test]
fn test_demo_auth() {
let auth = TwelvedataAuth::demo();
assert!(auth.has_credentials());
assert!(auth.is_demo());
assert_eq!(auth.masked_key(), Some("demo".to_string()));
}
#[test]
fn test_none_auth() {
let auth = TwelvedataAuth::none();
assert!(!auth.has_credentials());
assert!(!auth.is_demo());
assert_eq!(auth.masked_key(), None);
}
#[test]
fn test_sign_headers() {
let auth = TwelvedataAuth::new("my_secret_key");
let mut headers = HashMap::new();
auth.sign_headers(&mut headers);
assert_eq!(
headers.get("Authorization"),
Some(&"apikey my_secret_key".to_string())
);
}
#[test]
fn test_sign_headers_demo() {
let auth = TwelvedataAuth::demo();
let mut headers = HashMap::new();
auth.sign_headers(&mut headers);
assert_eq!(
headers.get("Authorization"),
Some(&"apikey demo".to_string())
);
}
#[test]
fn test_query_param() {
let auth = TwelvedataAuth::new("my_key");
let mut params = HashMap::new();
auth.add_query_param(&mut params);
assert_eq!(params.get("apikey"), Some(&"my_key".to_string()));
}
#[test]
fn test_masked_key() {
let auth = TwelvedataAuth::new("abcdefgh12345678");
assert_eq!(auth.masked_key(), Some("abcd...5678".to_string()));
let short_auth = TwelvedataAuth::new("short");
assert_eq!(short_auth.masked_key(), Some("****".to_string()));
}
}