ironfix_session/
config.rs1use ironfix_core::types::CompId;
12use std::time::Duration;
13
14#[derive(Debug, Clone)]
16pub struct SessionConfig {
17 pub sender_comp_id: CompId,
19 pub target_comp_id: CompId,
21 pub begin_string: String,
23 pub heartbeat_interval: Duration,
25 pub reset_on_logon: bool,
27 pub reset_on_logout: bool,
29 pub reset_on_disconnect: bool,
31 pub max_message_size: usize,
33 pub logon_timeout: Duration,
35 pub logout_timeout: Duration,
37 pub validate_checksum: bool,
39 pub validate_length: bool,
41 pub sender_sub_id: Option<String>,
43 pub target_sub_id: Option<String>,
45 pub sender_location_id: Option<String>,
47 pub target_location_id: Option<String>,
49}
50
51impl SessionConfig {
52 #[must_use]
59 pub fn new(
60 sender_comp_id: CompId,
61 target_comp_id: CompId,
62 begin_string: impl Into<String>,
63 ) -> Self {
64 Self {
65 sender_comp_id,
66 target_comp_id,
67 begin_string: begin_string.into(),
68 heartbeat_interval: Duration::from_secs(30),
69 reset_on_logon: false,
70 reset_on_logout: false,
71 reset_on_disconnect: false,
72 max_message_size: 1024 * 1024, logon_timeout: Duration::from_secs(10),
74 logout_timeout: Duration::from_secs(10),
75 validate_checksum: true,
76 validate_length: true,
77 sender_sub_id: None,
78 target_sub_id: None,
79 sender_location_id: None,
80 target_location_id: None,
81 }
82 }
83
84 #[must_use]
86 pub fn with_heartbeat_interval(mut self, interval: Duration) -> Self {
87 self.heartbeat_interval = interval;
88 self
89 }
90
91 #[must_use]
93 pub const fn with_reset_on_logon(mut self, reset: bool) -> Self {
94 self.reset_on_logon = reset;
95 self
96 }
97
98 #[must_use]
100 pub const fn with_max_message_size(mut self, size: usize) -> Self {
101 self.max_message_size = size;
102 self
103 }
104
105 #[must_use]
107 pub fn with_logon_timeout(mut self, timeout: Duration) -> Self {
108 self.logon_timeout = timeout;
109 self
110 }
111
112 #[must_use]
114 pub fn with_sender_sub_id(mut self, sub_id: impl Into<String>) -> Self {
115 self.sender_sub_id = Some(sub_id.into());
116 self
117 }
118
119 #[must_use]
121 pub fn with_target_sub_id(mut self, sub_id: impl Into<String>) -> Self {
122 self.target_sub_id = Some(sub_id.into());
123 self
124 }
125
126 #[must_use]
128 pub fn heartbeat_interval_secs(&self) -> u64 {
129 self.heartbeat_interval.as_secs()
130 }
131}
132
133#[derive(Debug, Default)]
135pub struct SessionConfigBuilder {
136 sender_comp_id: Option<CompId>,
137 target_comp_id: Option<CompId>,
138 begin_string: Option<String>,
139 heartbeat_interval: Option<Duration>,
140 reset_on_logon: bool,
141 max_message_size: Option<usize>,
142}
143
144impl SessionConfigBuilder {
145 #[must_use]
147 pub fn new() -> Self {
148 Self::default()
149 }
150
151 #[must_use]
153 pub fn sender_comp_id(mut self, id: CompId) -> Self {
154 self.sender_comp_id = Some(id);
155 self
156 }
157
158 #[must_use]
160 pub fn target_comp_id(mut self, id: CompId) -> Self {
161 self.target_comp_id = Some(id);
162 self
163 }
164
165 #[must_use]
167 pub fn begin_string(mut self, version: impl Into<String>) -> Self {
168 self.begin_string = Some(version.into());
169 self
170 }
171
172 #[must_use]
174 pub fn heartbeat_interval(mut self, interval: Duration) -> Self {
175 self.heartbeat_interval = Some(interval);
176 self
177 }
178
179 #[must_use]
181 pub const fn reset_on_logon(mut self, reset: bool) -> Self {
182 self.reset_on_logon = reset;
183 self
184 }
185
186 #[must_use]
191 pub fn build(self) -> SessionConfig {
192 let sender = self.sender_comp_id.expect("sender_comp_id is required");
193 let target = self.target_comp_id.expect("target_comp_id is required");
194 let begin_string = self.begin_string.unwrap_or_else(|| "FIX.4.4".to_string());
195
196 let mut config = SessionConfig::new(sender, target, begin_string);
197
198 if let Some(interval) = self.heartbeat_interval {
199 config.heartbeat_interval = interval;
200 }
201 config.reset_on_logon = self.reset_on_logon;
202 if let Some(size) = self.max_message_size {
203 config.max_message_size = size;
204 }
205
206 config
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213
214 #[test]
215 fn test_session_config_new() {
216 let sender = CompId::new("SENDER").unwrap();
217 let target = CompId::new("TARGET").unwrap();
218 let config = SessionConfig::new(sender, target, "FIX.4.4");
219
220 assert_eq!(config.sender_comp_id.as_str(), "SENDER");
221 assert_eq!(config.target_comp_id.as_str(), "TARGET");
222 assert_eq!(config.begin_string, "FIX.4.4");
223 assert_eq!(config.heartbeat_interval, Duration::from_secs(30));
224 }
225
226 #[test]
227 fn test_session_config_builder() {
228 let config = SessionConfigBuilder::new()
229 .sender_comp_id(CompId::new("SENDER").unwrap())
230 .target_comp_id(CompId::new("TARGET").unwrap())
231 .begin_string("FIX.4.2")
232 .heartbeat_interval(Duration::from_secs(60))
233 .reset_on_logon(true)
234 .build();
235
236 assert_eq!(config.begin_string, "FIX.4.2");
237 assert_eq!(config.heartbeat_interval, Duration::from_secs(60));
238 assert!(config.reset_on_logon);
239 }
240}