fixlite/
lib.rs

1pub mod fix;
2pub mod type_check;
3
4use std::iter::Peekable;
5use thiserror::Error;
6
7#[derive(Error, Debug)]
8pub enum FixError {
9    #[error("Invalid FIX message")]
10    InvalidMessage,
11    #[error("Invalid value for tag {0}")]
12    InvalidValue(u32),
13    #[error("Invalid enum value for tag {0}")]
14    InvalidEnumValue(&'static str),
15    #[error("Missing required field {0}")]
16    MissingField(&'static str),
17    #[error("UTF-8 parsing error")]
18    Utf8Error(#[from] std::str::Utf8Error),
19    #[error("DateTime parsing error")]
20    DateTimeError(#[from] chrono::ParseError),
21}
22
23pub trait FixDeserialize<'fix>: Sized {
24    fn from_fix(fix_message: &'fix [u8]) -> Result<Self, FixError> {
25        let fix_message_str = std::str::from_utf8(fix_message)?;
26        let mut fields = fix_message_str.split('\x01').peekable();
27        Self::deserialize_fields(&mut fields, |_| false)
28    }
29
30    fn from_fix_with_separator(fix_message: &'fix [u8], separator: char) -> Result<Self, FixError> {
31        let fix_message_str = std::str::from_utf8(fix_message)?;
32        let mut fields = fix_message_str.split(separator).peekable();
33        Self::deserialize_fields(&mut fields, |_| false)
34    }
35
36    fn deserialize_fields<I, F>(
37        fields: &mut Peekable<I>,
38        is_a_parent_tag: F,
39    ) -> Result<Self, FixError>
40    where
41        I: Iterator<Item = &'fix str>,
42        F: Fn(u32) -> bool;
43
44    fn is_known_tag(tag: u32) -> bool;
45}