1#[derive(Default, Clone, Debug)]
2pub struct Parser {
3 buffer: Vec<u8>,
4}
5
6impl Parser {
7 pub fn read_fix_message(&mut self) -> Result<Option<Vec<u8>>, ParserError> {
8 Ok(read_fix(&mut self.buffer))
9 }
10
11 pub fn add_to_stream(&mut self, read: &[u8]) {
12 self.buffer.extend_from_slice(read)
13 }
14
15 pub fn clear(&mut self) {
16 self.buffer.clear()
17 }
18}
19
20pub(crate) trait Find<T> {
21 fn find(&self, item: T) -> Option<usize>;
22}
23
24impl Find<&[u8]> for Vec<u8> {
25 fn find(&self, item: &[u8]) -> Option<usize> {
26 let mut index = 0;
27 for _c in self {
28 if item.len() >= self.len() - index {
29 return None;
30 }
31 if &self[index..index + item.len()] == item {
32 return Some(index);
33 }
34 index += 1;
35 }
36 None
37 }
38}
39impl Find<char> for Vec<u8> {
40 fn find(&self, item: char) -> Option<usize> {
41 let mut index = 0;
42 for c in self {
43 if c == &(item as u8) {
44 return Some(index);
45 }
46 index += 1;
47 }
48 None
49 }
50}
51impl Find<&[u8]> for [u8] {
52 fn find(&self, item: &[u8]) -> Option<usize> {
53 let mut index = 0;
54 for _c in self {
55 if item.len() >= self.len() - index {
56 return None;
57 }
58 if &self[index..index + item.len()] == item {
59 return Some(index);
60 }
61 index += 1;
62 }
63 None
64 }
65}
66impl Find<char> for [u8] {
67 fn find(&self, item: char) -> Option<usize> {
68 let mut index = 0;
69 for c in self {
70 if c == &(item as u8) {
71 return Some(index);
72 }
73 index += 1;
74 }
75 None
76 }
77}
78
79pub fn read_fix(buffer: &mut Vec<u8>) -> Option<Vec<u8>> {
82 if buffer.len() < 2 {
83 return None;
84 }
85 let pos: Option<usize> = buffer.find("8=".as_bytes());
86 if pos == None || pos == Some(usize::MAX) {
87 return None;
88 }
89 let pos = pos?;
90 buffer.drain(..pos); if let Some((len, mut pos)) = extract_length(&buffer) {
92 pos += len;
93 if buffer.len() < pos {
94 return None;
95 }
96 let found = buffer[pos - 1..].find("\x0110=".as_bytes());
97 pos = found? + pos - 1;
98 pos += 4;
100 let found = buffer[pos..].find('\x01');
101 pos += found?;
102 pos += 1;
103 return Some(buffer.drain(..pos).collect());
104 }
105 None
106}
107
108pub fn extract_length(buffer: &[u8]) -> Option<(usize, usize)> {
111 let start = buffer.find("\x019=".as_bytes())? + 3;
112 let end = buffer[start..].find('\x01')? + start;
113 let str_len = &buffer[start..end];
114 match std::str::from_utf8(str_len) {
115 Ok(s) => {
116 let out_len = s.parse::<usize>().ok()?;
117 Some((end + 1, out_len))
118 }
119 Err(_) => None,
120 }
121}
122
123pub fn read_version(buffer: &[u8]) -> Option<&str> {
124 let pos: Option<usize> = buffer.find("8=".as_bytes());
125 let pos = pos?;
126 let found = buffer[pos..].find('\x01');
127 let end = found?;
128 match std::str::from_utf8(&buffer[pos + 2..end]) {
129 Ok(s) => Some(s),
130 Err(_) => None,
131 }
132}
133
134pub fn read_msg_type(buffer: &[u8]) -> Option<&str> {
135 let pos: Option<usize> = buffer.find("\x0135=".as_bytes());
136 let pos = pos? + 4;
137 let found = buffer[pos..].find('\x01');
138 let end = found? + pos;
139 match std::str::from_utf8(&buffer[pos..end]) {
140 Ok(s) if s.len() > 0 => Some(s),
141 Ok(_) => None,
142 Err(_) => None,
143 }
144}
145
146#[derive(Debug)]
147pub enum ParserError {}
148
149#[cfg(test)]
150mod tests {
151 use crate::parser::Parser;
152
153 use super::read_msg_type;
154
155 #[test]
156 pub fn two_in_one() {
157 let buffer = b"8=FIX.4.4\x019=57\x0135=A\x0134=1\x0149=ISLD\x0152=00000000-00:00:00\x0156=TW\x0198=0\x01108=30\x0110=0\x018=FIX.4.4\x019=45\x0135=5\x0134=2\x0149=ISLD\x0152=00000000-00:00:00\x0156=TW\x0110=0\x01";
158 println!("{}", buffer.iter().map(|b| *b as char).collect::<String>());
159 let mut parser = Parser::default();
160 parser.add_to_stream(buffer);
161 let msg = parser.read_fix_message();
162 assert!(msg.is_ok());
163 if let Ok(msg) = msg {
164 assert!(msg.is_some());
165 assert!(!parser.buffer.is_empty());
166 println!(
167 "{}",
168 parser.buffer.iter().map(|b| *b as char).collect::<String>()
169 );
170 }
171 let msg = parser.read_fix_message();
172 assert!(msg.is_ok());
173 if let Ok(msg) = msg {
174 assert!(msg.is_some());
175 }
176 }
177
178 #[test]
179 pub fn test_read_msg_type() {
180 let buffer = b"8=FIX.4.4\x019=57\x0135=A\x0134=1\x0149=ISLD\x0152=00000000-00:00:00\x0156=TW\x0198=0\x01108=30\x0110=0\x018=FIX.4.4\x019=45\x0135=5\x0134=2\x0149=ISLD\x0152=00000000-00:00:00\x0156=TW\x0110=0\x01";
181 let msg_type = read_msg_type(buffer);
182 assert!(msg_type.is_some());
183 assert_eq!(msg_type.unwrap(), "A");
184 }
185
186 #[test]
187 pub fn test_read_msg_type_longer() {
188 let buffer = b"8=FIX.4.4\x019=57\x0135=AASDFA\x0134=1\x0149=ISLD\x0152=00000000-00:00:00\x0156=TW\x0198=0\x01108=30\x0110=0\x018=FIX.4.4\x019=45\x0135=5\x0134=2\x0149=ISLD\x0152=00000000-00:00:00\x0156=TW\x0110=0\x01";
189 let msg_type = read_msg_type(buffer);
190 assert!(msg_type.is_some());
191 assert_eq!(msg_type.unwrap(), "AASDFA");
192 }
193}