use std::fmt;
use dictionary::fields::{MsgSeqNum,OrigSendingTime,SenderCompID,SendingTime,TargetCompID};
use field::Field;
use field_type::FieldType;
use fix_version::FIXVersion;
use message::{BuildMessage,Message};
use message_version::MessageVersion;
pub trait BuildFIXTMessage: BuildMessage {
fn new_into_box(&self) -> Box<BuildFIXTMessage + Send>;
fn build(&self) -> Box<FIXTMessage + Send>;
}
pub trait FIXTMessageBuildable {
fn builder(&self) -> Box<BuildFIXTMessage + Send>;
}
pub trait FIXTMessage: Message {
fn new_into_box(&self) -> Box<FIXTMessage + Send>;
fn msg_type(&self) -> &'static [u8];
fn msg_seq_num(&self) -> <<MsgSeqNum as Field>::Type as FieldType>::Type;
fn sender_comp_id(&self) -> &<<SenderCompID as Field>::Type as FieldType>::Type;
fn target_comp_id(&self) -> &<<TargetCompID as Field>::Type as FieldType>::Type;
fn set_appl_ver_id(&mut self,message_version: MessageVersion);
fn is_poss_dup(&self) -> bool;
fn set_is_poss_dup(&mut self,is_poss_dup: bool);
fn sending_time(&self) -> <<SendingTime as Field>::Type as FieldType>::Type;
fn orig_sending_time(&self) -> <<OrigSendingTime as Field>::Type as FieldType>::Type;
fn set_orig_sending_time(&mut self,orig_sending_time: <<OrigSendingTime as Field>::Type as FieldType>::Type);
fn setup_fixt_session_header(&mut self,
msg_seq_num: Option<<<MsgSeqNum as Field>::Type as FieldType>::Type>,
sender_comp_id: <<SenderCompID as Field>::Type as FieldType>::Type,
target_comp_id: <<TargetCompID as Field>::Type as FieldType>::Type);
}
pub fn debug_format_fixt_message(message: &FIXTMessage, f: &mut fmt::Formatter) -> fmt::Result {
let mut buffer = Vec::new();
message.read(FIXVersion::FIXT_1_1,MessageVersion::FIX50SP2,&mut buffer);
let buffer: Vec<u8> = buffer.into_iter().map(|c| if c == b'\x01' { b'|' } else { c } ).collect();
write!(f,"{:?}",String::from_utf8_lossy(&buffer[..]))
}
impl fmt::Debug for FIXTMessage + Send {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
debug_format_fixt_message(self,f)
}
}
#[macro_export]
macro_rules! define_fixt_message {
( $message_name:ident $( : $message_type:expr => )* { $( $field_required:expr, $field_name:ident : $field_type:ty [$( $version:tt )*] $(=> REQUIRED_WHEN $required_when_expr:expr)* ),* $(),* } ) => {
define_message!($message_name $( : $message_type => )* {
$crate::message::REQUIRED, sender_comp_id: $crate::dictionary::fields::SenderCompID [FIX40..], $crate::message::REQUIRED, target_comp_id: $crate::dictionary::fields::TargetCompID [FIX40..], $crate::message::NOT_REQUIRED, appl_ver_id: $crate::dictionary::fields::ApplVerID [FIX40..], $crate::message::NOT_REQUIRED, appl_ext_id: $crate::dictionary::fields::ApplExtID [FIX50SP1..],
$crate::message::NOT_REQUIRED, cstm_appl_ver_id: $crate::dictionary::fields::CstmApplVerID [FIX50..],
$crate::message::NOT_REQUIRED, on_behalf_of_comp_id: $crate::dictionary::fields::OnBehalfOfCompID [FIX40..],
$crate::message::NOT_REQUIRED, deliver_to_comp_id: $crate::dictionary::fields::DeliverToCompID [FIX40..],
$crate::message::NOT_REQUIRED, secure_data_len: $crate::dictionary::fields::SecureDataLen [FIX40..],
$crate::message::NOT_REQUIRED, secure_data: $crate::dictionary::fields::SecureData [FIX40..],
$crate::message::REQUIRED, msg_seq_num: $crate::dictionary::fields::MsgSeqNum [FIX40..],
$crate::message::NOT_REQUIRED, sender_sub_id: $crate::dictionary::fields::SenderSubID [FIX40..],
$crate::message::NOT_REQUIRED, sender_location_id: $crate::dictionary::fields::SenderLocationID [FIX41..],
$crate::message::NOT_REQUIRED, target_sub_id: $crate::dictionary::fields::TargetSubID [FIX40..],
$crate::message::NOT_REQUIRED, target_location_id: $crate::dictionary::fields::TargetLocationID [FIX41..],
$crate::message::NOT_REQUIRED, on_behalf_of_sub_id: $crate::dictionary::fields::OnBehalfOfSubID [FIX40..],
$crate::message::NOT_REQUIRED, on_behalf_of_location_id: $crate::dictionary::fields::OnBehalfOfLocationID [FIX41..],
$crate::message::NOT_REQUIRED, deliver_to_sub_id: $crate::dictionary::fields::DeliverToSubID [FIX40..],
$crate::message::NOT_REQUIRED, deliver_to_location_id: $crate::dictionary::fields::DeliverToLocationID [FIX41..],
$crate::message::NOT_REQUIRED, poss_dup_flag: $crate::dictionary::fields::PossDupFlag [FIX40..],
$crate::message::NOT_REQUIRED, poss_resend: $crate::dictionary::fields::PossResend [FIX40..],
$crate::message::REQUIRED, sending_time: $crate::dictionary::fields::SendingTime [FIX40..],
$crate::message::NOT_REQUIRED, orig_sending_time: $crate::dictionary::fields::OrigSendingTime [FIX40..] => REQUIRED_WHEN |message: &$message_name,_| { message.poss_dup_flag },
$crate::message::NOT_REQUIRED, xml_data_len: $crate::dictionary::fields::XmlDataLen [FIX42..],
$crate::message::NOT_REQUIRED, xml_data: $crate::dictionary::fields::XmlData [FIX42..],
$crate::message::NOT_REQUIRED, message_encoding: $crate::dictionary::fields::MessageEncoding [FIX42..],
$crate::message::NOT_REQUIRED, last_msg_seq_num_processed: $crate::dictionary::fields::LastMsgSeqNumProcessed [FIX42..],
$crate::message::NOT_REQUIRED, on_behalf_of_sending_time: $crate::dictionary::fields::OnBehalfOfSendingTime [FIX42..FIX43],
$crate::message::NOT_REQUIRED, hops: $crate::dictionary::fields::NoHops [FIX43..],
$( $field_required, $field_name : $field_type [$( $version )*] $(=> REQUIRED_WHEN $required_when_expr)*, )*
$crate::message::NOT_REQUIRED, signature_length: $crate::dictionary::fields::SignatureLength [FIX40..],
$crate::message::NOT_REQUIRED, signature: $crate::dictionary::fields::Signature [FIX40..],
});
impl $message_name {
#[allow(unreachable_code)]
pub fn msg_type() -> &'static [u8] {
$( return $message_type )*;
b""
}
}
impl $crate::fixt::message::FIXTMessage for $message_name {
fn new_into_box(&self) -> Box<$crate::fixt::message::FIXTMessage + Send> {
Box::new($message_name::new())
}
fn msg_type(&self) -> &'static [u8] {
$message_name::msg_type()
}
fn msg_seq_num(&self) -> <<$crate::dictionary::fields::MsgSeqNum as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type {
self.msg_seq_num
}
fn sender_comp_id(&self) -> &<<$crate::dictionary::fields::SenderCompID as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type {
&self.sender_comp_id
}
fn target_comp_id(&self) -> &<<$crate::dictionary::fields::TargetCompID as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type {
&self.target_comp_id
}
fn set_appl_ver_id(&mut self,appl_ver_id: $crate::message_version::MessageVersion) {
self.appl_ver_id = Some(appl_ver_id);
}
fn is_poss_dup(&self) -> bool {
self.poss_dup_flag
}
fn set_is_poss_dup(&mut self,is_poss_dup: bool) {
self.poss_dup_flag = is_poss_dup;
}
fn sending_time(&self) -> <<$crate::dictionary::fields::SendingTime as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type {
self.sending_time
}
fn orig_sending_time(&self) -> <<$crate::dictionary::fields::OrigSendingTime as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type {
self.orig_sending_time
}
fn set_orig_sending_time(&mut self,orig_sending_time: <<$crate::dictionary::fields::OrigSendingTime as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type) {
self.orig_sending_time = orig_sending_time;
}
fn setup_fixt_session_header(&mut self,
msg_seq_num: Option<<<$crate::dictionary::fields::MsgSeqNum as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type>,
sender_comp_id: <<$crate::dictionary::fields::SenderCompID as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type,
target_comp_id: <<$crate::dictionary::fields::TargetCompID as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type) {
if let Some(msg_seq_num) = msg_seq_num {
self.msg_seq_num = msg_seq_num;
}
self.sender_comp_id = sender_comp_id;
self.target_comp_id = target_comp_id;
self.sending_time = <$crate::dictionary::fields::SendingTime as $crate::field::Field>::Type::new_now();
}
}
};
}