Skip to content

Commit

Permalink
♻️ Make rmessage group easier to works with
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurlm committed Dec 11, 2023
1 parent c7e3fe7 commit 2ace681
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 10 deletions.
18 changes: 8 additions & 10 deletions quickfix/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,35 +120,33 @@ impl Message {
}

/// Clone struct group part for a given tag and group index.
pub fn clone_group(&self, index: i32, tag: i32) -> Result<Group, QuickFixError> {
unsafe { FixMessage_copyGroup(self.0, index, tag) }
.map(Group)
.ok_or(QuickFixError::NullFunctionReturn)
pub fn clone_group(&self, index: i32, tag: i32) -> Option<Group> {
unsafe { FixMessage_copyGroup(self.0, index, tag) }.map(Group)
}

/// Read struct group part for a given tag and group index.
pub fn with_group<T, F>(&self, index: i32, tag: i32, f: F) -> Result<T, QuickFixError>
pub fn with_group<T, F>(&self, index: i32, tag: i32, f: F) -> Option<T>
where
F: FnOnce(&Group) -> T,
{
if let Some(ptr) = unsafe { FixMessage_getGroupRef(self.0, index, tag) } {
let obj = ManuallyDrop::new(Group(ptr));
Ok(f(&obj))
Some(f(&obj))
} else {
Err(QuickFixError::NullFunctionReturn)
None
}
}

/// Read or write struct group part for a given tag and group index.
pub fn with_group_mut<T, F>(&mut self, index: i32, tag: i32, f: F) -> Result<T, QuickFixError>
pub fn with_group_mut<T, F>(&mut self, index: i32, tag: i32, f: F) -> Option<T>
where
F: FnOnce(&mut Group) -> T,
{
if let Some(ptr) = unsafe { FixMessage_getGroupRef(self.0, index, tag) } {
let mut obj = ManuallyDrop::new(Group(ptr));
Ok(f(&mut obj))
Some(f(&mut obj))
} else {
Err(QuickFixError::NullFunctionReturn)
None
}
}
}
Expand Down
93 changes: 93 additions & 0 deletions quickfix/tests/test_message_group.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use msg_const::*;
use quickfix::*;

mod msg_const;

Expand All @@ -24,3 +25,95 @@ fn test_build_with_group() {
148=New great project available\u{1}10=205\u{1}"
);
}

#[test]
fn test_read_group_clone() {
let msg = build_news("Great news", &["Some new library", "are available", "soon"]).unwrap();
assert_eq!(msg.get_field(MSG_HEADLINE).unwrap(), "Great news");

// Read before
assert!(msg.clone_group(0, MSG_NO_LINES_OF_TEXT).is_none());

// Read configured lines
let group = msg.clone_group(1, MSG_NO_LINES_OF_TEXT).unwrap();
assert_eq!(group.get_field(MSG_TEXT).unwrap(), "Some new library");

let group = msg.clone_group(2, MSG_NO_LINES_OF_TEXT).unwrap();
assert_eq!(group.get_field(MSG_TEXT).unwrap(), "are available");

let group = msg.clone_group(3, MSG_NO_LINES_OF_TEXT).unwrap();
assert_eq!(group.get_field(MSG_TEXT).unwrap(), "soon");

// Read after
assert!(msg.clone_group(4, MSG_NO_LINES_OF_TEXT).is_none());
}

#[test]
fn test_read_group_ref() {
let msg = build_news("Great news", &["Some new library", "are available", "soon"]).unwrap();
assert_eq!(msg.get_field(MSG_HEADLINE).unwrap(), "Great news");

fn read_text(group: &Group) -> String {
group.get_field(MSG_TEXT).unwrap()
}

// Read before
assert!(msg.with_group(0, MSG_NO_LINES_OF_TEXT, read_text).is_none());

// Read configured lines
assert_eq!(
msg.with_group(1, MSG_NO_LINES_OF_TEXT, read_text).unwrap(),
"Some new library"
);
assert_eq!(
msg.with_group(2, MSG_NO_LINES_OF_TEXT, read_text).unwrap(),
"are available"
);
assert_eq!(
msg.with_group(3, MSG_NO_LINES_OF_TEXT, read_text).unwrap(),
"soon"
);

// Read after
assert!(msg.with_group(4, MSG_NO_LINES_OF_TEXT, read_text).is_none());
}

#[test]
fn test_modify_group() {
let mut msg = build_news("Great news", &["Some new library", "are available", "soon"]).unwrap();

// Check before
assert_eq!(
msg.as_string().unwrap(),
"9=70\u{1}35=B\u{1}33=3\u{1}\
58=Some new library\u{1}\
58=are available\u{1}\
58=soon\u{1}\
148=Great news\u{1}\
10=020\u{1}"
);

// Update valid group
assert!(msg
.with_group_mut(2, MSG_NO_LINES_OF_TEXT, |g| g
.set_field(MSG_TEXT, "will be available")
.unwrap())
.is_some());

// Update invalid group
assert!(msg
.with_group_mut(58, MSG_NO_LINES_OF_TEXT, |g| g
.set_field(MSG_TEXT, "whatever")
.unwrap())
.is_none());

// Check after
assert_eq!(
msg.as_string().unwrap(),
"9=74\u{1}35=B\u{1}33=3\u{1}\
58=Some new library\u{1}\
58=will be available\u{1}\
58=soon\u{1}148=Great news\u{1}\
10=127\u{1}"
);
}

0 comments on commit 2ace681

Please sign in to comment.