use crate::models::AuthRequest;
use crate::websocket::config::{ConnectionConfig, ConnectionConfigBuilder};
#[derive(Clone)]
pub struct WebSocketFactory {
auth: AuthRequest,
base_url: Option<String>,
}
impl WebSocketFactory {
pub fn new(auth: AuthRequest) -> Self {
Self {
auth,
base_url: None,
}
}
pub fn base_url(mut self, base: impl Into<String>) -> Self {
self.base_url = Some(base.into());
self
}
pub fn stock(&self) -> ConnectionConfigBuilder {
ConnectionConfig::builder(self.endpoint_for("stock"), self.auth.clone())
}
pub fn futopt(&self) -> ConnectionConfigBuilder {
ConnectionConfig::builder(self.endpoint_for("futopt"), self.auth.clone())
}
fn endpoint_for(&self, kind: &str) -> String {
let base = self
.base_url
.as_deref()
.unwrap_or(crate::urls::WS_BASE_ROOT);
format!(
"{}/{}/{}/streaming",
base.trim_end_matches('/'),
crate::urls::API_VERSION,
kind,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::urls::{FUTOPT_WS, STOCK_WS};
#[test]
fn test_default_stock_endpoint() {
let factory = WebSocketFactory::new(AuthRequest::with_api_key("k"));
let cfg = factory.stock().build();
assert_eq!(cfg.url, STOCK_WS);
}
#[test]
fn test_default_futopt_endpoint() {
let factory = WebSocketFactory::new(AuthRequest::with_api_key("k"));
let cfg = factory.futopt().build();
assert_eq!(cfg.url, FUTOPT_WS);
}
#[test]
fn test_custom_base_url_applied_to_stock() {
let factory = WebSocketFactory::new(AuthRequest::with_api_key("k"))
.base_url("wss://staging.fugle.tw/marketdata");
let cfg = factory.stock().build();
assert_eq!(
cfg.url,
"wss://staging.fugle.tw/marketdata/v1.0/stock/streaming",
);
}
#[test]
fn test_custom_base_url_applied_to_futopt() {
let factory = WebSocketFactory::new(AuthRequest::with_api_key("k"))
.base_url("ws://localhost:8080");
let cfg = factory.futopt().build();
assert_eq!(cfg.url, "ws://localhost:8080/v1.0/futopt/streaming");
}
#[test]
fn test_base_url_strips_trailing_slashes() {
let factory = WebSocketFactory::new(AuthRequest::with_api_key("k"))
.base_url("wss://example.com/marketdata///");
let cfg = factory.stock().build();
assert_eq!(
cfg.url,
"wss://example.com/marketdata/v1.0/stock/streaming",
);
}
#[test]
fn test_factory_yields_independent_builders() {
let factory = WebSocketFactory::new(AuthRequest::with_api_key("k"));
let a = factory.stock().message_buffer(2048).build();
let b = factory.stock().message_buffer(4096).build();
assert_eq!(a.message_buffer, 2048);
assert_eq!(b.message_buffer, 4096);
}
#[test]
fn test_chained_setters_compose_with_factory() {
let factory = WebSocketFactory::new(AuthRequest::with_api_key("k"))
.base_url("wss://staging.fugle.tw/marketdata");
let cfg = factory
.stock()
.message_buffer(8192)
.event_buffer(256)
.build();
assert_eq!(
cfg.url,
"wss://staging.fugle.tw/marketdata/v1.0/stock/streaming",
);
assert_eq!(cfg.message_buffer, 8192);
assert_eq!(cfg.event_buffer, 256);
}
}