Skip to content

Unofficial rust binding of QuickFIX library

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

arthurlm/quickfix-rs

Repository files navigation

QuickFIX Rust

CI workflow MSRV codecov dependency status

This project is an unofficial binding between quickfix library and Rust projects.

Features

  • Provide basic and safe API wrapper above quickfix library.
  • Run on any hardware and operating system supported by Rust Tier 1 (Windows 7+, MacOS 10.12+ & Linux).
  • Only include and compile what you need since project is split into minimal crates.
  • Message decoding / encoding including run-time validation.
  • Supports FIX versions 4x (version 5x can be build locally from XML spec file).
  • Spec driven run-time message validation.
  • Spec driven code generation of type-safe FIX messages, fields, and repeating groups.
  • Session state storage options: SQL, File, In Memory.
  • Logging options: stdout, stderr, log or any other crate if you implement your own trait.

Documentation

External website:

Examples

Here is the minimal application you can write to getting started with quickfix:

use std::{
    env,
    io::{stdin, Read},
    process::exit,
};

use quickfix::*;

#[derive(Default)]
pub struct MyApplication;

impl ApplicationCallback for MyApplication {
    // Implement whatever callback you need

    fn on_create(&self, _session: &SessionId) {
        // Do whatever you want here 😁
    }
}

fn main() -> Result<(), QuickFixError> {
    let args: Vec<_> = env::args().collect();
    let Some(config_file) = args.get(1) else {
        eprintln!("Bad program usage: {} <config_file>", args[0]);
        exit(1);
    };

    let settings = SessionSettings::try_from_path(config_file)?;
    let store_factory = FileMessageStoreFactory::try_new(&settings)?;
    let log_factory = LogFactory::try_new(&StdLogger::Stdout)?;
    let app = Application::try_new(&MyApplication)?;

    let mut acceptor = SocketAcceptor::try_new(&settings, &app, &store_factory, &log_factory)?;
    acceptor.start()?;

    println!(">> App running, press 'q' to quit");
    let mut stdin = stdin().lock();
    let mut stdin_buf = [0];
    loop {
        let _ = stdin.read_exact(&mut stdin_buf);
        if stdin_buf[0] == b'q' {
            break;
        }
    }

    acceptor.stop()?;
    Ok(())
}

You may consider checking out this directory for more examples.

Is it ready for production ?

Yes. But keep in mind that not every feature of the original FIX library are available. If some of your needs are missing: PR / feedbacks are welcomed 😁!

API MAY CHANGE IN FUTURE VERSION
Crate is still in the reviewing process. Feel free to participate and share your point of view on this github issue.

NOTE: I am personally not using for now the generated message struct. I know they works fine thanks to unit tests and can be used in production code. Feedback on this part are welcomed !

Project status

I am not actively developing many more features to this project.
To me it is actually pretty completed !

If something is missing to you, feel free to open an issue / create PR. Contribution are welcomed.

Build requirements

Following package must be install to build the library:

  • cmake
  • a C++ compiler (with C++17 support)
  • rustup / rustc / cargo (obviously 😉)
  • rustfmt for auto generated messages from spec.