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}