Skip to content

Commit

Permalink
✨ Add more field to dictionary_item
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurlm committed Mar 20, 2024
1 parent 44d317d commit 10bcc4a
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 5 deletions.
134 changes: 133 additions & 1 deletion quickfix/src/dictionary_item.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(missing_debug_implementations)]

use crate::{Dictionary, QuickFixError};
use crate::{DayOfWeek, Dictionary, QuickFixError};

/// Trait that represent quickfix configuration parameter.
///
Expand Down Expand Up @@ -77,6 +77,30 @@ impl_dictionary_item!(SocketConnectPort as i32);
pub struct SocketConnectHost<'a>(pub &'a str);
impl_dictionary_item!(SocketConnectHost as String);

/// Initiator port to connect from.
pub struct SocketConnectSourcePort(pub u32);
impl_dictionary_item!(SocketConnectSourcePort as i32);

/// Initiator host to connect from.
pub struct SocketConnectSourceHost<'a>(pub &'a str);
impl_dictionary_item!(SocketConnectSourceHost as String);

/// Set SO_REUSEADDR flag when creating socket.
pub struct SocketReuseAddress(pub bool);
impl_dictionary_item!(SocketReuseAddress);

/// Set TCP_NODELAY flag when creating socket.
pub struct SocketNodelay(pub bool);
impl_dictionary_item!(SocketNodelay);

/// Configure SO_SNDBUF socket parameter.
pub struct SocketSendBufferSize(pub u16);
impl_dictionary_item!(SocketSendBufferSize as i32);

/// Configure SO_RCVBUF socket parameter.
pub struct SocketReceiveBufferSize(pub u16);
impl_dictionary_item!(SocketReceiveBufferSize as i32);

/// Time in second to wait before reconnect.
pub struct ReconnectInterval(pub u16);
impl_dictionary_item!(ReconnectInterval as i32);
Expand All @@ -85,18 +109,66 @@ impl_dictionary_item!(ReconnectInterval as i32);
pub struct HeartBtInt(pub u16);
impl_dictionary_item!(HeartBtInt as i32);

/// Send redundant resend requests.
pub struct SendRedundantResendRequests(pub bool);
impl_dictionary_item!(SendRedundantResendRequests);

/// Send next expected message sequence number.
pub struct SendNextExpectedMsgSeqNum(pub bool);
impl_dictionary_item!(SendNextExpectedMsgSeqNum);

/// Use local time.
pub struct UseLocalTime(pub bool);
impl_dictionary_item!(UseLocalTime);

/// Session start time.
pub struct StartTime<'a>(pub &'a str);
impl_dictionary_item!(StartTime as String);

/// Session start day.
pub struct StartDay(pub DayOfWeek);
impl_dictionary_item!(StartDay);

/// Session end time.
pub struct EndTime<'a>(pub &'a str);
impl_dictionary_item!(EndTime as String);

/// Session end day.
pub struct EndDay(pub DayOfWeek);
impl_dictionary_item!(EndDay);

/// Logon time.
pub struct LogonTime<'a>(pub &'a str);
impl_dictionary_item!(LogonTime as String);

/// Logon day.
pub struct LogonDay(pub DayOfWeek);
impl_dictionary_item!(LogonDay);

/// Logon timeout.
pub struct LogonTimeout(pub u16);
impl_dictionary_item!(LogonTimeout as i32);

/// Logout time.
pub struct LogoutTime<'a>(pub &'a str);
impl_dictionary_item!(LogoutTime as String);

/// Logout day.
pub struct LogoutDay(pub DayOfWeek);
impl_dictionary_item!(LogoutDay);

/// Logout timeout.
pub struct LogoutTimeout(pub u16);
impl_dictionary_item!(LogoutTimeout as i32);

/// Application version ID.
pub struct DefaultApplVerID<'a>(pub &'a str);
impl_dictionary_item!(DefaultApplVerID as String);

/// Parse and use data dictionary.
pub struct UseDataDictionary(pub bool);
impl_dictionary_item!(UseDataDictionary);

/// Data dictionary XML spec path.
pub struct DataDictionary<'a>(pub &'a str);
impl_dictionary_item!(DataDictionary as String);
Expand All @@ -109,6 +181,66 @@ impl_dictionary_item!(TransportDataDictionary as String);
pub struct FileStorePath<'a>(pub &'a str);
impl_dictionary_item!(FileStorePath as String);

/// Validate message comp ID.
pub struct CheckCompID(pub bool);
impl_dictionary_item!(CheckCompID);

/// Validate message latency.
pub struct CheckLatency(pub bool);
impl_dictionary_item!(CheckLatency);

/// Max allowed latency.
pub struct MaxLatency(pub i32);
impl_dictionary_item!(MaxLatency);

/// Validate message header length and checksum.
pub struct ValidateLengthAndChecksum(pub bool);
impl_dictionary_item!(ValidateLengthAndChecksum);

/// Validate message fields sent in wrong order.
pub struct ValidateFieldsOutOfOrder(pub bool);
impl_dictionary_item!(ValidateFieldsOutOfOrder);

/// Validate message fields inner values.
pub struct ValidateFieldsHaveValues(pub bool);
impl_dictionary_item!(ValidateFieldsHaveValues);

/// Validate user custom fields.
pub struct ValidateUserDefinedFields(pub bool);
impl_dictionary_item!(ValidateUserDefinedFields);

/// Allow unknown message fields.
pub struct AllowUnknownMsgFields(pub bool);
impl_dictionary_item!(AllowUnknownMsgFields);

/// Preserve message fields order.
pub struct PreserveMessageFieldsOrder(pub bool);
impl_dictionary_item!(PreserveMessageFieldsOrder);

/// Reset FIX session on logon.
pub struct ResetOnLogon(pub bool);
impl_dictionary_item!(ResetOnLogon);

/// Reset FIX session on logout.
pub struct ResetOnLogout(pub bool);
impl_dictionary_item!(ResetOnLogout);

/// Reset FIX session on disconnection.
pub struct ResetOnDisconnect(pub bool);
impl_dictionary_item!(ResetOnDisconnect);

/// Refresh FIX session on logon.
pub struct RefreshOnLogon(pub bool);
impl_dictionary_item!(RefreshOnLogon);

/// Built-in HTTP server main port.
pub struct HttpAcceptPort(pub u32);
impl_dictionary_item!(HttpAcceptPort as i32);

/// Persist FIX messages.
pub struct PersistMessages(pub bool);
impl_dictionary_item!(PersistMessages);

impl DictionaryItem for (&'static str, &str) {
fn apply_param(&self, dict: &mut Dictionary) -> Result<(), QuickFixError> {
dict.set(self.0, self.1.to_string())
Expand Down
87 changes: 83 additions & 4 deletions quickfix/tests/test_dictionary_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,47 @@ fn test_build() {
&SocketAcceptPort(42),
&SocketConnectPort(56),
&SocketConnectHost("10.8.0.3"),
&SocketConnectSourcePort(69),
&SocketConnectSourceHost("10.8.0.4"),
&SocketReuseAddress(true),
&SocketNodelay(false),
&SocketSendBufferSize(4096),
&SocketReceiveBufferSize(8192),
&ReconnectInterval(20),
&HeartBtInt(30),
&SendRedundantResendRequests(true),
&SendNextExpectedMsgSeqNum(false),
&UseLocalTime(true),
&StartTime("00:00:05"),
&StartDay(DayOfWeek::Monday),
&EndTime("23:59:55"),
&EndDay(DayOfWeek::Saturday),
&LogonTime("12:00:00"),
&LogonDay(DayOfWeek::Tuesday),
&LogonTimeout(90),
&LogoutTime("18:00:00"),
&LogoutDay(DayOfWeek::Friday),
&LogoutTimeout(15),
&DefaultApplVerID("8"),
&UseDataDictionary(true),
&DataDictionary("foo/FIX50.xml"),
&TransportDataDictionary("bar/FIXT11.xml"),
&FileStorePath("my_store"),
&CheckCompID(true),
&CheckLatency(false),
&MaxLatency(-20),
&ValidateLengthAndChecksum(false),
&ValidateFieldsOutOfOrder(false),
&ValidateFieldsHaveValues(true),
&ValidateUserDefinedFields(true),
&AllowUnknownMsgFields(false),
&PreserveMessageFieldsOrder(true),
&ResetOnLogon(true),
&ResetOnLogout(true),
&ResetOnDisconnect(false),
&RefreshOnLogon(true),
&HttpAcceptPort(9090),
&PersistMessages(false),
&("foo", "bar"),
])
.unwrap();
Expand All @@ -33,17 +66,43 @@ fn test_build() {
dict.get::<String>("ConnectionType").as_deref(),
Ok("acceptor")
);
assert_eq!(dict.get::<i32>("SocketAcceptPort"), Ok(42));
assert_eq!(dict.get::<i32>("SocketConnectPort"), Ok(56));
assert_eq!(dict.get("SocketAcceptPort"), Ok(42));
assert_eq!(dict.get("SocketConnectPort"), Ok(56));
assert_eq!(
dict.get::<String>("SocketConnectHost").as_deref(),
Ok("10.8.0.3")
);
assert_eq!(dict.get::<i32>("ReconnectInterval"), Ok(20));
assert_eq!(dict.get::<i32>("HeartBtInt"), Ok(30));
assert_eq!(dict.get("SocketConnectSourcePort"), Ok(69));
assert_eq!(
dict.get::<String>("SocketConnectSourceHost").as_deref(),
Ok("10.8.0.4")
);
assert_eq!(dict.get("SocketReuseAddress"), Ok(true));
assert_eq!(dict.get("SocketNodelay"), Ok(false));
assert_eq!(dict.get("SocketSendBufferSize"), Ok(4096));
assert_eq!(dict.get("SocketReceiveBufferSize"), Ok(8192));

assert_eq!(dict.get("ReconnectInterval"), Ok(20));
assert_eq!(dict.get("HeartBtInt"), Ok(30));

assert_eq!(dict.get("SendRedundantResendRequests"), Ok(true));
assert_eq!(dict.get("SendNextExpectedMsgSeqNum"), Ok(false));

assert_eq!(dict.get("UseLocalTime"), Ok(true));
assert_eq!(dict.get::<String>("StartTime").as_deref(), Ok("00:00:05"));
assert_eq!(dict.get::<String>("StartDay").as_deref(), Ok("MO"));
assert_eq!(dict.get::<String>("EndTime").as_deref(), Ok("23:59:55"));
assert_eq!(dict.get::<String>("EndDay").as_deref(), Ok("SA"));

assert_eq!(dict.get::<String>("LogonTime").as_deref(), Ok("12:00:00"));
assert_eq!(dict.get::<String>("LogonDay").as_deref(), Ok("TU"));
assert_eq!(dict.get("LogonTimeout"), Ok(90));
assert_eq!(dict.get::<String>("LogoutTime").as_deref(), Ok("18:00:00"));
assert_eq!(dict.get::<String>("LogoutDay").as_deref(), Ok("FR"));
assert_eq!(dict.get("LogoutTimeout"), Ok(15));

assert_eq!(dict.get::<String>("DefaultApplVerID").as_deref(), Ok("8"));
assert_eq!(dict.get("UseDataDictionary"), Ok(true));
assert_eq!(
dict.get::<String>("DataDictionary").as_deref(),
Ok("foo/FIX50.xml")
Expand All @@ -57,4 +116,24 @@ fn test_build() {
Ok("my_store")
);
assert_eq!(dict.get::<String>("foo").as_deref(), Ok("bar"));

assert_eq!(dict.get("CheckCompID"), Ok(true));
assert_eq!(dict.get("CheckLatency"), Ok(false));
assert_eq!(dict.get("MaxLatency"), Ok(-20));
assert_eq!(dict.get("ValidateLengthAndChecksum"), Ok(false));
assert_eq!(dict.get("ValidateFieldsOutOfOrder"), Ok(false));
assert_eq!(dict.get("ValidateFieldsHaveValues"), Ok(true));
assert_eq!(dict.get("ValidateUserDefinedFields"), Ok(true));
assert_eq!(dict.get("AllowUnknownMsgFields"), Ok(false));
assert_eq!(dict.get("PreserveMessageFieldsOrder"), Ok(true));

assert_eq!(dict.get("ResetOnLogon"), Ok(true));
assert_eq!(dict.get("ResetOnLogout"), Ok(true));
assert_eq!(dict.get("ResetOnDisconnect"), Ok(false));

assert_eq!(dict.get("RefreshOnLogon"), Ok(true));

assert_eq!(dict.get("HttpAcceptPort"), Ok(9090));

assert_eq!(dict.get("PersistMessages"), Ok(false));
}

0 comments on commit 10bcc4a

Please sign in to comment.