{"id":46064563,"url":"https://github.com/mcsakoff/rs-fastlib","last_synced_at":"2026-03-01T12:07:00.987Z","repository":{"id":246823182,"uuid":"823377549","full_name":"mcsakoff/rs-fastlib","owner":"mcsakoff","description":"FAST (FIX Adapted for STreaming protocol) decoder/encoder library","archived":false,"fork":false,"pushed_at":"2026-02-19T10:50:34.000Z","size":154,"stargazers_count":11,"open_issues_count":1,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-19T13:48:28.832Z","etag":null,"topics":["decoder","encoder","protocol"],"latest_commit_sha":null,"homepage":"https://docs.rs/fastlib","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcsakoff.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-MIT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-07-02T23:35:30.000Z","updated_at":"2026-02-19T10:50:38.000Z","dependencies_parsed_at":"2024-07-29T23:48:18.989Z","dependency_job_id":"1ffeaac2-895a-4434-a8ce-564988034679","html_url":"https://github.com/mcsakoff/rs-fastlib","commit_stats":null,"previous_names":["mcsakoff/rs-fastlib"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/mcsakoff/rs-fastlib","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcsakoff%2Frs-fastlib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcsakoff%2Frs-fastlib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcsakoff%2Frs-fastlib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcsakoff%2Frs-fastlib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcsakoff","download_url":"https://codeload.github.com/mcsakoff/rs-fastlib/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcsakoff%2Frs-fastlib/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29969243,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T11:43:06.159Z","status":"ssl_error","status_checked_at":"2026-03-01T11:43:03.887Z","response_time":124,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decoder","encoder","protocol"],"created_at":"2026-03-01T12:07:00.477Z","updated_at":"2026-03-01T12:07:00.982Z","avatar_url":"https://github.com/mcsakoff.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FIX/FAST Protocol Decoder/Encoder\n[![Crates.io](https://img.shields.io/crates/v/fastlib?style=flat-square)](https://crates.io/crates/fastlib)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/mcsakoff/rs-fastlib/rust.yml?branch=main\u0026style=flat-square)](https://github.com/mcsakoff/rs-fastlib/actions/workflows/rust.yml?query=branch%3Amain)\n[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE-MIT)\n\n**FAST** (**F**IX **A**dapted for **ST**reaming protocol) is a space and processing efficient encoding method for message oriented data streams.\n\nThe FAST protocol has been developed as part of the FIX Market Data Optimization Working Group.\nFAST data compression algorithm is designed to optimize electronic exchange of financial data, particularly for high volume,\nlow latency data dissemination. It significantly reduces bandwidth requirements and latency between sender and receiver.\nFAST works especially well at improving performance during periods of peak message rates.\n\n_Technical Specification_: https://www.fixtrading.org/standards/fast-online/  \n_Supported version_: 1.x.1\n\n\n## Usage\n\nAdd to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfastlib = \"0.3\"\n```\n\n### Serialize/Deserialize using serde\n\nFor templates defined in XML, e.g.:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003ctemplates xmlns=\"http://www.fixprotocol.org/ns/fast/td/1.1\"\u003e\n    \u003ctemplate name=\"MsgHeader\"\u003e\n        \u003cuInt32 id=\"34\" name=\"MsgSeqNum\"/\u003e\n        \u003cuInt64 id=\"52\" name=\"SendingTime\"/\u003e\n    \u003c/template\u003e\n    \u003ctemplate id=\"1\" name=\"MDHeartbeat\"\u003e\n        \u003ctemplateRef name=\"MsgHeader\"/\u003e\n    \u003c/template\u003e\n    \u003ctemplate id=\"2\" name=\"MDLogout\"\u003e\n        \u003ctemplateRef name=\"MsgHeader\"/\u003e\n        \u003cstring id=\"58\" name=\"Text\" presence=\"optional\"/\u003e\n    \u003c/template\u003e\n\u003c/templates\u003e\n```\n\nDefine the message types in Rust:\n\n```rust\nuse serde::{Serialize, Deserialize};\n\n#[derive(Serialize, Deserialize)]\nenum Message {\n    MDHeartbeat(Heartbeat),\n    MDLogout(Logout),\n}\n\n#[derive(Serialize, Deserialize)]\nstruct MsgHeader {\n    #[serde(rename = \"MsgSeqNum\")]\n    msg_seq_num: u32,\n    #[serde(rename = \"SendingTime\")]\n    sending_time: u64,\n}\n\n#[derive(Serialize, Deserialize)]\n#[serde(rename_all = \"PascalCase\")]\nstruct Heartbeat {\n    #[serde(flatten)]\n    msg_header: MsgHeader,\n}\n\n#[derive(Serialize, Deserialize)]\n#[serde(rename_all = \"PascalCase\")]\nstruct Logout {\n    #[serde(flatten)]\n    msg_header: MsgHeader,\n    text: Option\u003cString\u003e,\n}\n```\n\nSome implementation guidelines:\n\n* `\u003ctemplates\u003e` must be implemented as `enum`;\n* `\u003cdecimal\u003e` can be deserialized to `f64` or `fastlib::Decimal` (if you need to preserve original scale);\n* `\u003cbyteVector\u003e` is a `Vec\u003cu8\u003e` and must be prefixed with `#[serde(with = \"serde_bytes\")]`;\n* `\u003csequence\u003e` is a `Vec\u003cSequenceItem\u003e`, where `SequenceItem` is a `struct`;\n* `\u003cgroup\u003e` is a nested `struct`;\n* fields with optional presence are `Option\u003c...\u003e`;\n* static template reference can be plain fields from the template or flattened `struct`,\n* dynamic template references must be `Box\u003cMessage\u003e` with `#[serde(rename = \"templateRef:N\")]`, where `N`\n  is a 0-based index of the `\u003cteplateRef\u003e` in its group.\n\nTo deserialize a message call `fastlib::from_slice`, `fastlib::from_buffer`, `fastlib::from_vec`, `fastlib::from_bytes` or more generic `fastlib::from_reader` or `fastlib::from_stream`:\n\n```rust\nuse fastlib::Decoder;\n\n// Create a decoder from XML templates.\nlet mut decoder = Decoder::new_from_xml(include_str!(\"templates.xml\"))?;\n\n// Raw data that contains one message.\nlet raw_data: Vec\u003cu8\u003e = vec![ ... ];\n\n// Deserialize a message.\nlet msg: Message = fastlib::from_slice(\u0026mut decoder, \u0026raw_data)?;\n```\n\nTo serialize a message call `fastlib::to_vec`, `fastlib::to_bytes`, `fastlib::to_writer`, `fastlib::to_stream` or `fastlib::to_buffer`:\n\n```rust\nuse fastlib::Encoder;\n\n// Create an encoder from XML templates.\nlet mut encoder = Encoder::new_from_xml(include_str!(\"templates.xml\"))?;\n\n// Message to serialize.\nlet msg = Message::MDHeartbeat{\n    Heartbeat {\n        ...\n    }\n};\n\n// Serialize a message.\nlet raw: Vec\u003cu8\u003e = fastlib::to_vec(\u0026mut encoder, \u0026msg)?;\n```\n\n### Decode to JSON\n\n```rust\nuse fastlib::Decoder;\nuse fastlib::JsonMessageFactory;\n\n// Create a decoder from XML templates.\nlet mut decoder = Decoder::new_from_xml(include_str!(\"templates.xml\"))?;\n\n// Raw data that contains one message.\nlet raw_data: Vec\u003cu8\u003e = vec![ ... ];\n\n// Create a JSON message factory.\nlet mut msg = JsonMessageFactory::new();\n\n// Decode the message.\ndecoder.decode_vec(raw_data, \u0026mut msg)?;\n\nprintln!(\"{}\", msg.json);\n```\n\n### Decode using own message factory\n\n**NOTE:** Decoding using own message factory is only required if very specific process of decoding\ninto very specific message types is needed. In most cases using `serde` is the way to go!\n\nMake a new struct that implements `fastlib::MessageFactory` trait:\n\n```rust\nuse fastlib::{MessageFactory, Value};\n\npub struct MyMessageFactory {\n}\n\nimpl MessageFactory for MyMessageFactory {\n    // ... your implementation here ...\n}\n```\n\nYou have to implement callbacks that will be called during message decoding:\n\n```rust\npub trait MessageFactory {\n    // Process template id\n    fn start_template(\u0026mut self, id: u32, name: \u0026str);\n    fn stop_template(\u0026mut self);\n    \n    // Process field value\n    fn set_value(\u0026mut self, id: u32, name: \u0026str, value: Option\u003cValue\u003e);\n    \n    // Process sequence\n    fn start_sequence(\u0026mut self, id: u32, name: \u0026str, length: u32);\n    fn start_sequence_item(\u0026mut self, index: u32);\n    fn stop_sequence_item(\u0026mut self);\n    fn stop_sequence(\u0026mut self);\n    \n    // Process group\n    fn start_group(\u0026mut self, name: \u0026str);\n    fn stop_group(\u0026mut self);\n    \n    // Process template ref\n    fn start_template_ref(\u0026mut self, name: \u0026str, dynamic: bool);\n    fn stop_template_ref(\u0026mut self);\n}\n```\n\nFor message factory implementation examples see `fastlib::text::TextMessageFactory` and `fastlib::text::JsonMessageFactory`.\n\nThen create a decoder from templates XML file and decode a message:\n\n```rust\nuse fastlib::Decoder;\n\n// Create a decoder from XML templates.\nlet mut decoder = Decoder::new_from_xml(include_str!(\"templates.xml\"))?;\n\n// Raw data that contains one message.\nlet raw_data: Vec\u003cu8\u003e = vec![ ... ];\n\n// Create a message factory.\nlet mut msg = MyMessageFactory{};\n\n// Decode the message.\ndecoder.decode_vec(raw_data, \u0026mut msg)?;\n```\n\n## Examples\n\n- [fast-tools](https://github.com/mcsakoff/rs-fast-tools)\n- [quotesdirectlib](https://github.com/mcsakoff/rs-quotesdirect)\n\n## License\n\nThis project is licensed under the [MIT license](LICENSE-MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcsakoff%2Frs-fastlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcsakoff%2Frs-fastlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcsakoff%2Frs-fastlib/lists"}