5个不稳定版本
0.3.1 | 2024年7月29日 |
---|---|
0.3.0 | 2024年7月23日 |
0.2.1 | 2024年7月11日 |
0.2.0 | 2024年7月6日 |
0.1.0 | 2024年7月3日 |
#431 在 解析器实现
每月443次下载
325KB
8K SLoC
FIX/FAST协议解码器/编码器
FAST (FIX ASTreaming protocol) 是一种用于面向消息的数据流的节省空间和处理效率的编码方法。
FAST协议是作为FIX市场数据优化工作组的一部分开发的。FAST数据压缩算法旨在优化金融数据的电子交换,尤其是针对高容量、低延迟的数据分发。它显著降低了发送者和接收者之间的带宽需求和延迟。FAST在高峰消息率期间尤其擅长提高性能。
技术规范: https://www.fixtrading.org/standards/fast-online/
支持版本: 1.x.1
使用方法
添加到您的 Cargo.toml
[dependencies]
fastlib = "0.3"
使用serde序列化/反序列化
例如,对于在XML中定义的模板:
<?xml version="1.0" encoding="UTF-8" ?>
<templates xmlns="http://www.fixprotocol.org/ns/fast/td/1.1">
<template name="MsgHeader">
<uInt32 id="34" name="MsgSeqNum"/>
<uInt64 id="52" name="SendingTime"/>
</template>
<template id="1" name="MDHeartbeat">
<templateRef name="MsgHeader"/>
</template>
<template id="2" name="MDLogout">
<templateRef name="MsgHeader"/>
<string id="58" name="Text" presence="optional"/>
</template>
</templates>
在Rust中定义消息类型
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
enum Message {
MDHeartbeat(Heartbeat),
MDLogout(Logout),
}
#[derive(Serialize, Deserialize)]
struct MsgHeader {
#[serde(rename = "MsgSeqNum")]
msg_seq_num: u32,
#[serde(rename = "SendingTime")]
sending_time: u64,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Heartbeat {
#[serde(flatten)]
msg_header: MsgHeader,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Logout {
#[serde(flatten)]
msg_header: MsgHeader,
text: Option<String>,
}
一些实现指南
<templates>
必须实现为enum
;<decimal>
可以反序列化为f64
或fastlib::Decimal
(如果需要保留原始缩放比例);<byteVector>
是一个Vec<u8>
,并且必须以#[serde(with = "serde_bytes")]
前缀;<sequence>
是一个Vec<SequenceItem>
,其中SequenceItem
是一个struct
;<group>
是一个嵌套的struct
;- 可选存在的字段是
Option<...>
; - 静态模板引用可以是模板的普通字段或展平的
struct
; - 动态模板引用必须是带有
#[serde(rename = "templateRef:N")]
的Box<Message>
,其中N
是其组中<templateRef>
的0基于索引。
要反序列化消息,请调用 fastlib::from_vec
,fastlib::from_bytes
或 from_stream
;
use fastlib::Decoder;
// Create a decoder from XML templates.
let mut decoder = Decoder::new_from_xml(include_str!("templates.xml"))?;
// Raw data that contains one message.
let raw_data: Vec<u8> = vec![ ... ];
// Deserialize a message.
let msg: Message = fastlib::from_vec(&mut decoder, raw_data)?;
要序列化消息,请调用 fastlib::to_vec
,fastlib::to_bytes
或 to_stream
;
use fastlib::Encoder;
// Create a encoder from XML templates.
let mut encoder = Encoder::new_from_xml(include_str!("templates.xml"))?;
// Message to serialize.
let msg = Message::MDHeartbeat{
Heartbeat {
...
}
};
// Serialize a message.
let raw: Vec<u8> = fastlib::to_vec(&mut encoder, &msg)?;
解码为JSON;
use fastlib::Decoder;
use fastlib::JsonMessageFactory;
// Create a decoder from XML templates.
let mut decoder = Decoder::new_from_xml(include_str!("templates.xml"))?;
// Raw data that contains one message.
let raw_data: Vec<u8> = vec![ ... ];
// Create a JSON message factory.
let mut msg = JsonMessageFactory::new();
// Decode the message.
decoder.decode_vec(raw_data, &mut msg)?;
println!("{}", msg.json);
使用自己的消息工厂解码;
创建一个新的实现 fastlib::MessageFactory
特性的结构体;
use fastlib::{MessageFactory, Value};
pub struct MyMessageFactory {
}
impl MessageFactory for MyMessageFactory {
// ... your implementation here ...
}
您必须实现消息解码期间将被调用的回调函数;
pub trait MessageFactory {
// Process template id
fn start_template(&mut self, id: u32, name: &str);
fn stop_template(&mut self);
// Process field value
fn set_value(&mut self, id: u32, name: &str, value: Option<Value>);
// Process sequence
fn start_sequence(&mut self, id: u32, name: &str, length: u32);
fn start_sequence_item(&mut self, index: u32);
fn stop_sequence_item(&mut self);
fn stop_sequence(&mut self);
// Process group
fn start_group(&mut self, name: &str);
fn stop_group(&mut self);
// Process template ref
fn start_template_ref(&mut self, name: &str, dynamic: bool);
fn stop_template_ref(&mut self);
}
有关示例,请参阅 fastlib::text::TextMessageFactory
或 fastlib::text::JsonMessageFactory
的实现,但更有可能的是,您将想要构建自己的消息结构体;
然后从模板XML文件创建解码器并解码消息;
use fastlib::Decoder;
// Create a decoder from XML templates.
let mut decoder = Decoder::new_from_xml(include_str!("templates.xml"))?;
// Raw data that contains one message.
let raw_data: Vec<u8> = vec![ ... ];
// Create a message factory.
let mut msg = MyMessageFactory{};
// Decode the message.
decoder.decode_vec(raw_data, &mut msg)?;
示例
许可证
本项目受MIT许可证许可;
依赖项
~2–3MB
~50K SLoC