use ironfix_core::message::MsgType;
#[derive(Debug, Clone)]
pub struct OutboundMessage {
msg_type: MsgType,
fields: Vec<(u32, Vec<u8>)>,
}
impl OutboundMessage {
#[must_use]
pub fn new(msg_type: MsgType) -> Self {
Self {
msg_type,
fields: Vec::new(),
}
}
#[must_use]
pub fn msg_type(&self) -> &MsgType {
&self.msg_type
}
pub fn push_raw(&mut self, tag: u32, value: impl Into<Vec<u8>>) -> &mut Self {
self.fields.push((tag, value.into()));
self
}
pub fn push_str(&mut self, tag: u32, value: &str) -> &mut Self {
self.push_raw(tag, value.as_bytes().to_vec())
}
pub fn push_int(&mut self, tag: u32, value: i64) -> &mut Self {
self.push_raw(tag, value.to_string().into_bytes())
}
pub fn push_uint(&mut self, tag: u32, value: u64) -> &mut Self {
self.push_raw(tag, value.to_string().into_bytes())
}
pub fn push_char(&mut self, tag: u32, value: char) -> &mut Self {
let mut buf = [0u8; 4];
let s = value.encode_utf8(&mut buf);
self.push_raw(tag, s.as_bytes().to_vec())
}
pub fn push_bool(&mut self, tag: u32, value: bool) -> &mut Self {
self.push_raw(tag, if value { b"Y".to_vec() } else { b"N".to_vec() })
}
#[must_use]
pub fn fields(&self) -> &[(u32, Vec<u8>)] {
&self.fields
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_outbound_message_fields_in_order() {
let mut msg = OutboundMessage::new(MsgType::NewOrderSingle);
msg.push_str(11, "ORDER-1")
.push_char(54, '1')
.push_uint(38, 100)
.push_int(9999, -5)
.push_bool(59, true);
assert_eq!(msg.msg_type(), &MsgType::NewOrderSingle);
let fields = msg.fields();
assert_eq!(fields[0], (11, b"ORDER-1".to_vec()));
assert_eq!(fields[1], (54, b"1".to_vec()));
assert_eq!(fields[2], (38, b"100".to_vec()));
assert_eq!(fields[3], (9999, b"-5".to_vec()));
assert_eq!(fields[4], (59, b"Y".to_vec()));
}
}