Skip to content

Commit

Permalink
✨ Impl Clone for SessionID
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurlm committed Nov 13, 2023
1 parent ac4ed37 commit 21fc532
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 7 deletions.
3 changes: 2 additions & 1 deletion quickfix-bind/include/quickfix_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ extern "C"
void FixSocketAcceptor_delete(FixSocketAcceptor_t *obj);

FixSessionID_t *FixSessionID_new(const char *beginString, const char *senderCompID, const char *targetCompID, const char *sessionQualifier);
FixSessionID_t *FixSessionID_copy(const FixSessionID_t *src);
const char *FixSessionID_getBeginString(const FixSessionID_t *session);
const char *FixSessionID_getSenderCompID(const FixSessionID_t *session);
const char *FixSessionID_getTargetCompID(const FixSessionID_t *session);
const char *FixSessionID_getSessionQualifier(const FixSessionID_t *session);
int8_t FixSessionID_isFIXT(const FixSessionID_t *session);
const char *FixSessionID_toString(const FixSessionID *session);
const char *FixSessionID_toString(const FixSessionID_t *session);
void FixSessionID_delete(FixSessionID_t *session);

FixMessage_t *FixMessage_new();
Expand Down
16 changes: 16 additions & 0 deletions quickfix-bind/src/quickfix_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,22 @@ extern "C"
}
}

FixSessionID_t *
FixSessionID_copy(const FixSessionID_t *src)
{
RETURN_VAL_IF_NULL(src, NULL);

auto fix_obj = (FIX::SessionID *)(src);
try
{
return (FixSessionID_t *)(new FIX::SessionID(*fix_obj));
}
catch (std::exception &ex)
{
return NULL;
}
}

const char *FixSessionID_getBeginString(const FixSessionID_t *session)
{
RETURN_VAL_IF_NULL(session, NULL);
Expand Down
3 changes: 2 additions & 1 deletion quickfix-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct FixFileLogFactory_t(NonNull<ffi::c_void>);
#[repr(transparent)]
pub struct FixApplication_t(NonNull<ffi::c_void>);

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct FixSessionID_t(NonNull<ffi::c_void>);

Expand Down Expand Up @@ -90,6 +90,7 @@ extern "C" {
targetCompID: *const ffi::c_char,
sessionQualifier: *const ffi::c_char,
) -> Option<FixSessionID_t>;
pub fn FixSessionID_copy(src: FixSessionID_t) -> Option<FixSessionID_t>;
pub fn FixSessionID_getBeginString(obj: FixSessionID_t) -> Option<NonNull<ffi::c_char>>;
pub fn FixSessionID_getSenderCompID(obj: FixSessionID_t) -> Option<NonNull<ffi::c_char>>;
pub fn FixSessionID_getTargetCompID(obj: FixSessionID_t) -> Option<NonNull<ffi::c_char>>;
Expand Down
34 changes: 29 additions & 5 deletions quickfix/src/session_id.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use std::{ffi::CString, fmt};

use quickfix_ffi::{
FixSessionID_delete, FixSessionID_getBeginString, FixSessionID_getSenderCompID,
FixSessionID_getSessionQualifier, FixSessionID_getTargetCompID, FixSessionID_isFIXT,
FixSessionID_toString,
FixSessionID_copy, FixSessionID_delete, FixSessionID_getBeginString,
FixSessionID_getSenderCompID, FixSessionID_getSessionQualifier, FixSessionID_getTargetCompID,
FixSessionID_isFIXT, FixSessionID_new, FixSessionID_t, FixSessionID_toString,
};

use crate::{utils::read_checked_cstr, QuickFixError};

pub struct SessionId(pub(crate) quickfix_ffi::FixSessionID_t);
pub struct SessionId(pub(crate) FixSessionID_t);

impl SessionId {
pub fn try_new(
Expand All @@ -23,7 +23,7 @@ impl SessionId {
let ffi_session_qualifier = CString::new(session_qualifier)?;

match unsafe {
quickfix_ffi::FixSessionID_new(
FixSessionID_new(
ffi_begin_string.as_ptr(),
ffi_sender_comp_id.as_ptr(),
ffi_target_comp_id.as_ptr(),
Expand All @@ -35,6 +35,10 @@ impl SessionId {
}
}

pub fn try_clone(&self) -> Option<Self> {
unsafe { FixSessionID_copy(self.0) }.map(Self)
}

pub fn get_begin_string(&self) -> Option<String> {
unsafe { FixSessionID_getBeginString(self.0) }.map(read_checked_cstr)
}
Expand Down Expand Up @@ -63,6 +67,12 @@ impl SessionId {
}
}

impl Clone for SessionId {
fn clone(&self) -> Self {
self.try_clone().expect("Fail to copy SessionID")
}
}

impl fmt::Debug for SessionId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("SessionId").field(&self.as_string()).finish()
Expand All @@ -74,3 +84,17 @@ impl Drop for SessionId {
unsafe { FixSessionID_delete(self.0) }
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_clone_have_distinct_ptr() {
let session1 = SessionId::try_new("FIX.4.1", "FOO", "BAR", "").unwrap();

let session2 = session1.clone();
assert_ne!(session1.0, session2.0);
assert_eq!(session1.as_string(), session2.as_string());
}
}
13 changes: 13 additions & 0 deletions quickfix/tests/test_session_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,16 @@ fn test_fixt() {
assert!(!session1.is_fixt());
assert!(session2.is_fixt());
}

#[test]
fn test_clone() {
let session1 = SessionId::try_new("FIX.4.1", "FOO", "BAR", "").unwrap();
assert_eq!(session1.as_string(), "FIX.4.1:FOO->BAR");

let session2 = session1.clone();
assert_eq!(session2.as_string(), "FIX.4.1:FOO->BAR");

// Test do not crash after drop
drop(session1);
assert_eq!(session2.as_string(), "FIX.4.1:FOO->BAR");
}

0 comments on commit 21fc532

Please sign in to comment.