-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Summary
Several design issues in hotfix-message affect correctness, API ergonomics, and performance.
Problems
Asymmetric get/set on Message
Message implements Part by delegating get_field_map() to the body, but overrides set() to route fields to the correct part (header/body/trailer) based on FieldLocation. This means message.get(SENDER_COMP_ID) returns Missing even when the field exists in the header, while message.set(SENDER_COMP_ID, "X") correctly routes to the header.
Part trait has too many responsibilities
Part combines field access, mutation, group management, and length calculation. The length calculation semantics differ between parts — Header skips BeginString/BodyLength, Trailer skips CheckSum, Body has no exclusions — but these differences are hidden behind the same interface.
encode() mutates the message
Message::encode() sets BodyLength and CheckSum on self as a side effect. Encoding a message shouldn't require &mut self, and encoding twice may produce unexpected results.
Per-field allocation during parsing
Every parsed field allocates a Vec<u8> via .to_vec(). For high-throughput FIX parsing, a zero-copy approach where fields borrow from the input buffer would avoid allocation on every field.
MessageBuilder naming
MessageBuilder is a parser/factory, not a builder. The name conflicts with the builder pattern and is confusing since actual message construction uses Message::new() + Part::set().
tag_from_bytes doesn't validate input
Non-digit bytes produce garbage results via silent arithmetic overflow rather than returning None.
tags.rs vs session_fields.rs
The same session-level fields (BeginString, BodyLength, MsgType, CheckSum) are defined in both tags.rs and re-exported from session_fields.rs/fixt11, with different modules importing from different sources.