use crate::application::{Application, NoOpApplication};
use ironfix_session::config::SessionConfig;
use std::sync::Arc;
use std::time::Duration;
#[derive(Debug)]
pub struct EngineBuilder<A: Application = NoOpApplication> {
application: Arc<A>,
sessions: Vec<SessionConfig>,
use_tls: bool,
connect_timeout: Duration,
reconnect_interval: Duration,
max_reconnect_attempts: u32,
}
impl Default for EngineBuilder<NoOpApplication> {
fn default() -> Self {
Self::new()
}
}
impl EngineBuilder<NoOpApplication> {
#[must_use]
pub fn new() -> Self {
Self {
application: Arc::new(NoOpApplication),
sessions: Vec::new(),
use_tls: false,
connect_timeout: Duration::from_secs(30),
reconnect_interval: Duration::from_secs(5),
max_reconnect_attempts: 10,
}
}
}
impl<A: Application> EngineBuilder<A> {
#[must_use]
pub fn with_application<B: Application>(self, application: B) -> EngineBuilder<B> {
EngineBuilder {
application: Arc::new(application),
sessions: self.sessions,
use_tls: self.use_tls,
connect_timeout: self.connect_timeout,
reconnect_interval: self.reconnect_interval,
max_reconnect_attempts: self.max_reconnect_attempts,
}
}
#[must_use]
pub fn add_session(mut self, config: SessionConfig) -> Self {
self.sessions.push(config);
self
}
#[must_use]
pub const fn with_tls(mut self, enabled: bool) -> Self {
self.use_tls = enabled;
self
}
#[must_use]
pub fn with_connect_timeout(mut self, timeout: Duration) -> Self {
self.connect_timeout = timeout;
self
}
#[must_use]
pub fn with_reconnect_interval(mut self, interval: Duration) -> Self {
self.reconnect_interval = interval;
self
}
#[must_use]
pub const fn with_max_reconnect_attempts(mut self, attempts: u32) -> Self {
self.max_reconnect_attempts = attempts;
self
}
#[must_use]
pub fn sessions(&self) -> &[SessionConfig] {
&self.sessions
}
#[must_use]
pub const fn use_tls(&self) -> bool {
self.use_tls
}
#[must_use]
pub const fn connect_timeout(&self) -> Duration {
self.connect_timeout
}
#[must_use]
pub const fn reconnect_interval(&self) -> Duration {
self.reconnect_interval
}
#[must_use]
pub const fn max_reconnect_attempts(&self) -> u32 {
self.max_reconnect_attempts
}
#[must_use]
pub fn application(&self) -> Arc<A> {
Arc::clone(&self.application)
}
}
#[cfg(test)]
mod tests {
use super::*;
use ironfix_core::types::CompId;
#[test]
fn test_engine_builder_default() {
let builder = EngineBuilder::new();
assert!(!builder.use_tls());
assert_eq!(builder.connect_timeout(), Duration::from_secs(30));
assert_eq!(builder.max_reconnect_attempts(), 10);
assert!(builder.sessions().is_empty());
}
#[test]
fn test_engine_builder_with_session() {
let config = SessionConfig::new(
CompId::new("SENDER").unwrap(),
CompId::new("TARGET").unwrap(),
"FIX.4.4",
);
let builder = EngineBuilder::new()
.add_session(config)
.with_tls(true)
.with_connect_timeout(Duration::from_secs(60));
assert_eq!(builder.sessions().len(), 1);
assert!(builder.use_tls());
assert_eq!(builder.connect_timeout(), Duration::from_secs(60));
}
}