This project is organized as a multirepo, consisting of multiple underlying crates, some of which are:
- trafix — an umbrella crate wrapping the 2 below.
- trafix-codec — a low-level library for high-performance parsing, encoding, and validation of FIX messages.
- trafix-engine — a full-featured FIX engine with session management, transports, and persistence built on top of
trafix-codec.
trafix-codec is the foundation crate: it provides control over FIX messages manipulation.
-
Message creation: Version-agnostic FIX message creation using a type-safe builder.
- Type-safe builder for
Message. - Allows custom fields.
- Prevents construction of invalid
Messages.
- Type-safe builder for
-
Message decoding: Version-agnostic FIX message decoding with a focus on correctness.
- SOH-based frame parsing (
tag=value\x01) - Support for FIX session-level messages
- Support for message validation
- SOH-based frame parsing (
-
Message encoding: Deterministic FIX message serialization with automatic framing.
- Correct handling of
BeginString (8),BodyLength (9), andCheckSum (10) - Supports arbitrary field order while enforcing FIX wire rules
- Efficient buffer-based encoding using (
Bytes/BytesMut)
- Correct handling of
use trafix_codec::message::{
Message,
field::{
Field,
value::{begin_string::BeginString, msg_type::MsgType},
},
};
fn main() {
// Create the FIX message builder
let builder = Message::builder(BeginString::FIX44, MsgType::Logout);
// Create a custom field (to be added in header)
let custom_header_field = Field::Custom {
tag: 22,
value: b"custom_header_field".to_vec(),
};
// Create a custom field (to be added in body)
let custom_body_field1 = Field::Custom {
tag: 40000,
value: b"custom_body_field1".to_vec(),
};
// Create a custom field (to be added in body)
let custom_body_field2 = Field::Custom {
tag: 50000,
value: b"custom_body_field2".to_vec(),
};
// build the message after adding the needed fields.
let message = builder
.with_header(custom_header_field)
.with_field(custom_body_field1)
.with_field(custom_body_field2)
.build();
// encode the message into bytes
let encoded_message = message.encode();
println!("{:?}", encoded_message);
// decoding example; decoding and encoding a message results in the same bytes output.
// Raw FIX message
let input = "8=FIX.4.4\x019=148\x0135=A\x0134=1080\x0149=TESTBUY1\x0152=20180920-18:14:19.508\x0156=TESTSELL1\x0111=636730640278898634\x0115=USD\x0121=2\x0138=7000\x0140=1\x0154=1\x0155=MSFT\x0160=20180920-18:14:19.492\x0110=089\x01";
// decode the input
let message2 = Message::decode(input).expect("Input is valid");
// encode the message into bytes
let encoded_message2 = message2.encode();
println!("{:?}", encoded_message2);
}