use serde::{Deserialize, Serialize};
use super::ProtocolOptions;
use crate::timestamp::{TimestampFormat, TimestampFormatter};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum HttpVersion {
#[default]
#[serde(rename = "http1", alias = "http/1.1", alias = "1.1")]
Http1,
#[serde(rename = "http2", alias = "http/2", alias = "2")]
Http2,
#[serde(rename = "auto")]
Auto,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectionOptions {
#[serde(default)]
pub http_version: HttpVersion,
#[serde(default = "default_auto_reconnect")]
pub auto_reconnect: bool,
#[serde(default = "default_reconnect_delay_ms")]
pub reconnect_delay_ms: u64,
#[serde(default = "default_max_reconnect_delay_ms")]
pub max_reconnect_delay_ms: u64,
#[serde(default)]
pub max_reconnect_attempts: Option<u32>,
#[serde(default)]
pub timestamp_format: TimestampFormat,
#[serde(default = "default_ping_interval_ms")]
pub ping_interval_ms: u64,
#[serde(default)]
pub ws_local_bind_addresses: Vec<String>,
#[serde(default)]
pub disable_compression: bool,
#[serde(default = "default_ws_lazy_connect")]
pub ws_lazy_connect: bool,
#[serde(default)]
pub protocol: ProtocolOptions,
}
fn default_auto_reconnect() -> bool {
true
}
fn default_reconnect_delay_ms() -> u64 {
1000
}
fn default_max_reconnect_delay_ms() -> u64 {
30000
}
fn default_ping_interval_ms() -> u64 {
5000
}
fn default_ws_lazy_connect() -> bool {
true
}
impl Default for ConnectionOptions {
fn default() -> Self {
Self {
http_version: HttpVersion::default(),
auto_reconnect: true,
reconnect_delay_ms: 1000,
max_reconnect_delay_ms: 30000,
max_reconnect_attempts: None,
timestamp_format: TimestampFormat::Iso8601,
ping_interval_ms: 5000,
ws_local_bind_addresses: Vec::new(),
disable_compression: false,
ws_lazy_connect: true,
protocol: ProtocolOptions::default(),
}
}
}
impl ConnectionOptions {
pub fn new() -> Self {
Self::default()
}
pub fn with_http_version(mut self, version: HttpVersion) -> Self {
self.http_version = version;
self
}
pub fn with_auto_reconnect(mut self, enabled: bool) -> Self {
self.auto_reconnect = enabled;
self
}
pub fn with_reconnect_delay_ms(mut self, delay_ms: u64) -> Self {
self.reconnect_delay_ms = delay_ms;
self
}
pub fn with_max_reconnect_delay_ms(mut self, max_delay_ms: u64) -> Self {
self.max_reconnect_delay_ms = max_delay_ms;
self
}
pub fn with_max_reconnect_attempts(mut self, max_attempts: Option<u32>) -> Self {
self.max_reconnect_attempts = max_attempts;
self
}
pub fn with_timestamp_format(mut self, format: TimestampFormat) -> Self {
self.timestamp_format = format;
self
}
pub fn create_formatter(&self) -> TimestampFormatter {
TimestampFormatter::new(self.timestamp_format)
}
pub fn with_ping_interval_ms(mut self, ms: u64) -> Self {
self.ping_interval_ms = ms;
self
}
pub fn with_ws_local_bind_addresses(mut self, addresses: Vec<String>) -> Self {
self.ws_local_bind_addresses = addresses;
self
}
pub fn with_disable_compression(mut self, disable: bool) -> Self {
self.disable_compression = disable;
self
}
pub fn with_ws_lazy_connect(mut self, lazy: bool) -> Self {
self.ws_lazy_connect = lazy;
self
}
pub fn with_protocol(mut self, protocol: ProtocolOptions) -> Self {
self.protocol = protocol;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_ws_lazy_connect_is_true() {
let opts = ConnectionOptions::default();
assert!(opts.ws_lazy_connect);
}
#[test]
fn with_ws_lazy_connect_sets_field() {
let opts = ConnectionOptions::default().with_ws_lazy_connect(true);
assert!(opts.ws_lazy_connect);
}
#[test]
fn serde_roundtrip_ws_lazy_connect() {
let opts = ConnectionOptions::default().with_ws_lazy_connect(true);
let json = serde_json::to_string(&opts).unwrap();
let deserialized: ConnectionOptions = serde_json::from_str(&json).unwrap();
assert!(deserialized.ws_lazy_connect);
}
#[test]
fn serde_missing_ws_lazy_connect_defaults_true() {
let json = r#"{"auto_reconnect": true}"#;
let deserialized: ConnectionOptions = serde_json::from_str(json).unwrap();
assert!(deserialized.ws_lazy_connect);
}
}