use crate::stream::StreamApi;
use crate::{CHAINSTREAM_BASE_URL, CHAINSTREAM_STREAM_URL};
#[derive(Debug, Clone)]
pub struct ChainStreamClientOptions {
pub server_url: Option<String>,
pub stream_url: Option<String>,
pub auto_connect_websocket: bool,
pub debug: bool,
}
impl Default for ChainStreamClientOptions {
fn default() -> Self {
Self {
server_url: None,
stream_url: None,
auto_connect_websocket: true,
debug: false,
}
}
}
pub trait TokenProvider: Send + Sync {
fn get_token(&self) -> String;
}
pub struct StaticTokenProvider {
token: String,
}
impl StaticTokenProvider {
pub fn new(token: &str) -> Self {
Self {
token: token.to_string(),
}
}
}
impl TokenProvider for StaticTokenProvider {
fn get_token(&self) -> String {
self.token.clone()
}
}
pub struct ChainStreamClient {
access_token: String,
pub server_url: String,
pub stream_url: String,
pub stream: StreamApi,
pub debug: bool,
}
impl ChainStreamClient {
pub fn new(access_token: &str, options: Option<ChainStreamClientOptions>) -> Self {
let opts = options.unwrap_or_default();
let server_url = opts
.server_url
.unwrap_or_else(|| CHAINSTREAM_BASE_URL.to_string());
let stream_url = opts
.stream_url
.unwrap_or_else(|| CHAINSTREAM_STREAM_URL.to_string());
let stream = StreamApi::new(&stream_url, access_token);
Self {
access_token: access_token.to_string(),
server_url,
stream_url,
stream,
debug: opts.debug,
}
}
pub fn new_with_token_provider<T: TokenProvider>(
token_provider: &T,
options: Option<ChainStreamClientOptions>,
) -> Self {
Self::new(&token_provider.get_token(), options)
}
pub fn get_access_token(&self) -> &str {
&self.access_token
}
pub async fn close(&self) {
self.stream.disconnect().await;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_client_creation() {
let client = ChainStreamClient::new("test-token", None);
assert_eq!(client.get_access_token(), "test-token");
assert_eq!(client.server_url, CHAINSTREAM_BASE_URL);
assert_eq!(client.stream_url, CHAINSTREAM_STREAM_URL);
}
#[test]
fn test_client_with_options() {
let options = ChainStreamClientOptions {
server_url: Some("https://custom-api.com".to_string()),
stream_url: Some("wss://custom-ws.com".to_string()),
auto_connect_websocket: false,
debug: true,
};
let client = ChainStreamClient::new("test-token", Some(options));
assert_eq!(client.server_url, "https://custom-api.com");
assert_eq!(client.stream_url, "wss://custom-ws.com");
assert!(client.debug);
}
#[test]
fn test_static_token_provider() {
let provider = StaticTokenProvider::new("my-token");
assert_eq!(provider.get_token(), "my-token");
let client = ChainStreamClient::new_with_token_provider(&provider, None);
assert_eq!(client.get_access_token(), "my-token");
}
}