1use std::{error::Error, fmt};
2
3use anyhow::Result;
4
5use crate::fields::basic_types::*;
6
7#[derive(Debug)]
8pub enum DeserializeError {
9 GarbledMessage(String),
11 Logout,
12 Reject {
13 msg_type: Option<FixString>,
14 seq_num: SeqNum,
15 tag: Option<TagNum>,
16 reason: ParseRejectReason,
17 },
18}
19
20impl fmt::Display for DeserializeError {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 match self {
23 DeserializeError::GarbledMessage(reason) => write!(f, "garbled message: {}", reason),
24 DeserializeError::Logout => write!(f, "MsgSeqNum missing"),
25 DeserializeError::Reject {
26 tag: Some(tag),
27 reason,
28 ..
29 } => write!(f, "{reason:?} (tag={tag})"),
30 DeserializeError::Reject {
31 tag: None, reason, ..
32 } => write!(f, "{reason:?}"),
33 }
34 }
35}
36
37impl Error for DeserializeError {}
38
39impl From<RawMessageError> for DeserializeError {
40 fn from(error: RawMessageError) -> Self {
41 match error {
42 RawMessageError::Incomplete => {
43 DeserializeError::GarbledMessage("Incomplete message data".to_owned())
44 }
45 RawMessageError::Garbled => {
46 DeserializeError::GarbledMessage("Message not well formed".to_owned())
47 }
48 RawMessageError::InvalidChecksum => {
49 DeserializeError::GarbledMessage("Invalid checksum".to_owned())
50 }
51 }
52 }
53}
54
55#[derive(Clone, Copy, Debug, Eq, PartialEq)]
56#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
57#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
58pub enum ParseRejectReason {
59 ValueIsIncorrect,
60 TagSpecifiedWithoutAValue,
61 IncorrectDataFormatForValue,
62 TagAppearsMoreThanOnce,
63 TagSpecifiedOutOfRequiredOrder,
64 RequiredTagMissing,
65 IncorrectNumingroupCountForRepeatingGroup,
66 TagNotDefinedForThisMessageType,
67 UndefinedTag,
68 RepeatingGroupFieldsOutOfOrder,
69 InvalidTagNumber,
70 InvalidMsgtype,
71 SendingtimeAccuracyProblem,
72 CompidProblem,
73}
74
75#[derive(Debug, thiserror::Error)]
76enum DeserializeErrorInternal {
77 #[error("Incomplete")]
78 Incomplete,
79 #[error("{0:?}")]
80 Error(ParseRejectReason),
81}
82
83fn deserialize_tag<'a>(bytes: &'a [u8], tag: &'a [u8]) -> Result<&'a [u8], RawMessageError> {
84 if bytes.len() < tag.len() {
85 Err(RawMessageError::Incomplete)
86 } else if bytes.starts_with(tag) {
87 Ok(&bytes[tag.len()..])
88 } else {
89 Err(RawMessageError::Garbled)
90 }
91}
92
93fn deserialize_checksum(bytes: &[u8]) -> Result<(&[u8], u8), RawMessageError> {
94 if bytes.len() < 4 {
95 return Err(RawMessageError::Incomplete);
96 }
97
98 let mut value: u8 = 0;
99 for b in &bytes[0..3] {
100 match b {
101 n @ b'0'..=b'9' => {
102 value = value
103 .checked_mul(10)
104 .and_then(|v| v.checked_add(n - b'0'))
105 .ok_or(RawMessageError::InvalidChecksum)?;
106 }
107 _ => return Err(RawMessageError::InvalidChecksum),
108 }
109 }
110
111 if bytes[3] != b'\x01' {
112 return Err(RawMessageError::InvalidChecksum);
113 }
114
115 Ok((&bytes[4..], value))
116}
117
118fn deserialize_str(bytes: &[u8]) -> Result<(&[u8], &FixStr), DeserializeErrorInternal> {
119 for (i, b) in bytes.iter().enumerate() {
120 match b {
121 0x00 | 0x02..=0x1f | 0x80..=0xff => {
123 return Err(DeserializeErrorInternal::Error(
124 ParseRejectReason::ValueIsIncorrect,
125 ));
126 }
127 b'\x01' => {
129 if i == 0 {
130 return Err(DeserializeErrorInternal::Error(
131 ParseRejectReason::TagSpecifiedWithoutAValue,
132 ));
133 } else {
134 return Ok((&bytes[i + 1..], unsafe {
136 FixStr::from_ascii_unchecked(&bytes[..i])
137 }));
138 }
139 }
140 _ => {}
141 }
142 }
143
144 Err(DeserializeErrorInternal::Incomplete)
145}
146
147fn deserialize_length(bytes: &[u8]) -> Result<(&[u8], Length), DeserializeErrorInternal> {
148 let mut value: Length = 0;
149 for (i, b) in bytes.iter().enumerate() {
150 match b {
151 n @ b'0'..=b'9' => {
152 value = value
153 .checked_mul(10)
154 .and_then(|v| v.checked_add(Length::from(n - b'0')))
155 .ok_or(DeserializeErrorInternal::Error(
156 ParseRejectReason::ValueIsIncorrect,
157 ))?;
158 }
159 b'\x01' => {
160 if i == 0 {
161 return Err(DeserializeErrorInternal::Error(
162 ParseRejectReason::TagSpecifiedWithoutAValue,
163 ));
164 } else if value == 0 {
165 return Err(DeserializeErrorInternal::Error(
166 ParseRejectReason::ValueIsIncorrect,
167 ));
168 } else {
169 return Ok((&bytes[i + 1..], value));
170 }
171 }
172 _ => {
173 return Err(DeserializeErrorInternal::Error(
174 ParseRejectReason::IncorrectDataFormatForValue,
175 ));
176 }
177 }
178 }
179
180 Err(DeserializeErrorInternal::Incomplete)
181}
182
183#[derive(Debug)]
184pub struct RawMessage<'a> {
185 pub begin_string: &'a FixStr,
186 pub body: &'a [u8],
187 pub checksum: u8,
188}
189
190#[derive(Debug, thiserror::Error)]
191pub enum RawMessageError {
192 #[error("Incomplete")]
193 Incomplete,
194 #[error("Garbled")]
195 Garbled,
196 #[error("Invalid checksum")]
197 InvalidChecksum,
198}
199
200impl From<DeserializeErrorInternal> for RawMessageError {
201 fn from(d: DeserializeErrorInternal) -> RawMessageError {
202 match d {
203 DeserializeErrorInternal::Incomplete => RawMessageError::Incomplete,
204 DeserializeErrorInternal::Error(_) => RawMessageError::Garbled,
205 }
206 }
207}
208
209pub fn raw_message(bytes: &[u8]) -> Result<(&[u8], RawMessage<'_>), RawMessageError> {
210 let orig_bytes = bytes;
211
212 let bytes = deserialize_tag(bytes, b"8=")?;
213 let (bytes, begin_string) = deserialize_str(bytes)?;
214
215 let bytes = deserialize_tag(bytes, b"9=")?;
216 let (bytes, body_length) = deserialize_length(bytes)?;
217 let body_length = usize::from(body_length);
218
219 const CHECKSUM_LEN: usize = 4;
220 if bytes.len() < body_length + CHECKSUM_LEN {
221 return Err(RawMessageError::Incomplete);
222 }
223
224 let body = &bytes[..body_length];
225 let bytes = &bytes[body_length..];
226
227 let calculated_checksum = orig_bytes[0..orig_bytes.len() - bytes.len()]
228 .iter()
229 .fold(0, |acc: u8, x| acc.wrapping_add(*x));
230
231 let bytes = deserialize_tag(bytes, b"10=")?;
232 let (bytes, checksum) = deserialize_checksum(bytes)?;
233 if calculated_checksum != checksum {
234 return Err(RawMessageError::InvalidChecksum);
235 }
236 Ok((
237 bytes,
238 RawMessage {
239 begin_string,
240 body,
241 checksum,
242 },
243 ))
244}
245
246#[derive(Debug)]
250pub struct Deserializer<'de> {
251 raw_message: RawMessage<'de>,
252 buf: &'de [u8],
253 msg_type: Option<std::ops::Range<usize>>,
254 seq_num: Option<SeqNum>,
255 current_tag: Option<TagNum>,
256 tmp_tag: Option<TagNum>,
259}
260
261impl Deserializer<'_> {
262 pub fn from_raw_message(raw_message: RawMessage) -> Deserializer {
263 let buf = raw_message.body;
264 Deserializer {
265 raw_message,
266 buf,
267 msg_type: None,
268 seq_num: None,
269 current_tag: None,
270 tmp_tag: None,
271 }
272 }
273
274 pub fn begin_string(&self) -> FixString {
275 self.raw_message.begin_string.to_owned()
276 }
277
278 pub fn body_length(&self) -> Length {
279 self.raw_message.body.len() as Length
280 }
281
282 pub fn check_sum(&self) -> FixString {
283 FixString::from_ascii_lossy(format!("{:03}", self.raw_message.checksum).into_bytes())
284 }
285
286 pub fn set_seq_num(&mut self, seq_num: SeqNum) {
287 debug_assert!(self.seq_num.is_none());
288
289 self.seq_num = Some(seq_num);
290 }
291
292 fn try_find_msg_seq_num(&mut self) -> Result<SeqNum, DeserializeError> {
295 let seq_num_tag = b"34=";
296
297 let start_index = self
298 .buf
299 .windows(seq_num_tag.len())
300 .position(|window| window == seq_num_tag)
301 .ok_or(DeserializeError::Logout)?;
302 self.buf = &self.buf[start_index + seq_num_tag.len()..];
303
304 self.deserialize_seq_num()
305 }
306
307 pub fn reject(&mut self, tag: Option<TagNum>, reason: ParseRejectReason) -> DeserializeError {
308 let seq_num = if let Some(seq_num) = self.seq_num {
309 seq_num
310 } else {
311 match self.try_find_msg_seq_num() {
312 Ok(seq_num) => seq_num,
313 Err(err) => return err,
314 }
315 };
316
317 DeserializeError::Reject {
318 msg_type: self.msg_type.clone().map(|msg_type| {
319 FixString::from_ascii_lossy(self.raw_message.body[msg_type].to_vec())
320 }),
321 seq_num,
322 tag,
323 reason,
324 }
325 }
326
327 pub fn repeating_group_fields_out_of_order(
328 &mut self,
329 expected_tags: &[u16],
330 processed_tags: &[u16],
331 current_tag: u16,
332 ) -> DeserializeError {
333 let mut current_tag_found = false;
334 'outer: for processed_tag in processed_tags {
335 for expected_tag in expected_tags {
336 if expected_tag == processed_tag {
337 if current_tag_found {
338 return self.reject(
339 Some(*processed_tag),
340 ParseRejectReason::RepeatingGroupFieldsOutOfOrder,
341 );
342 } else {
343 continue 'outer;
344 }
345 } else if *expected_tag == current_tag {
346 current_tag_found = true;
347 }
348 }
349 }
350 debug_assert!(false);
352 self.reject(None, ParseRejectReason::RepeatingGroupFieldsOutOfOrder)
353 }
354
355 pub fn put_tag(&mut self, tag: TagNum) {
356 self.tmp_tag = Some(tag);
357 }
358
359 pub fn range_to_fixstr(&self, range: std::ops::Range<usize>) -> &FixStr {
360 unsafe { FixStr::from_ascii_unchecked(&self.raw_message.body[range]) }
361 }
362
363 pub fn deserialize_msg_type(&mut self) -> Result<std::ops::Range<usize>, DeserializeError> {
365 let raw_message_pointer = self.raw_message.body.as_ptr();
366
367 let msg_type_range = {
368 let Ok(deser_str) = self.deserialize_str() else {
369 return Err(self.reject(Some(35), ParseRejectReason::InvalidMsgtype));
370 };
371 let msg_type_pointer = deser_str.as_bytes().as_ptr();
372 let msg_type_start_index =
373 unsafe { msg_type_pointer.offset_from(raw_message_pointer) } as usize;
374 let msg_type_len = deser_str.len();
375 msg_type_start_index..(msg_type_start_index + msg_type_len)
376 };
377
378 self.msg_type = Some(msg_type_range.clone());
379 Ok(msg_type_range)
380 }
381
382 pub fn deserialize_tag_num(&mut self) -> Result<Option<TagNum>, DeserializeError> {
385 if self.tmp_tag.is_some() {
386 return Ok(self.tmp_tag.take());
387 }
388
389 match self.buf {
390 [] => return Ok(None),
392 [b'0' | b'=', ..] => return Err(self.reject(None, ParseRejectReason::InvalidTagNumber)),
394 _ => {}
395 }
396
397 let mut value: TagNum = 0;
398 for i in 0..self.buf.len() {
399 match unsafe { self.buf.get_unchecked(i) } {
401 n @ b'0'..=b'9' => {
402 value = value
403 .checked_mul(10)
404 .and_then(|v| v.checked_add((n - b'0') as TagNum))
405 .ok_or_else(|| self.reject(None, ParseRejectReason::InvalidTagNumber))?;
407 }
408 b'=' => {
409 if value == 0 {
410 return Err(
411 self.reject(self.current_tag, ParseRejectReason::InvalidTagNumber)
412 );
413 } else {
414 self.current_tag = Some(value);
415 self.buf = &self.buf[i + 1..];
416 return Ok(Some(value));
417 }
418 }
419 _ => return Err(self.reject(None, ParseRejectReason::InvalidTagNumber)),
421 }
422 }
423
424 Err(DeserializeError::GarbledMessage(format!(
426 "no more data to parse tag {:?}",
427 self.current_tag
428 )))
429 }
430
431 pub fn deserialize_int(&mut self) -> Result<Int, DeserializeError> {
438 let negative = match self.buf {
439 [] => {
441 return Err(DeserializeError::GarbledMessage(format!(
442 "no more data to parse tag {:?}",
443 self.current_tag
444 )));
445 }
446 [b'\x01', ..] => {
447 return Err(self.reject(
448 self.current_tag,
449 ParseRejectReason::TagSpecifiedWithoutAValue,
450 ));
451 }
452 [b'-', b'\x01', ..] => {
453 return Err(self.reject(
454 self.current_tag,
455 ParseRejectReason::IncorrectDataFormatForValue,
456 ));
457 }
458 [b'-', buf @ ..] => {
459 self.buf = buf;
460 true
461 }
462 _ => false,
463 };
464
465 let mut value: Int = 0;
466 for i in 0..self.buf.len() {
467 match unsafe { self.buf.get_unchecked(i) } {
469 n @ b'0'..=b'9' => {
470 value = value
471 .checked_mul(10)
472 .and_then(|v| v.checked_add((n - b'0') as Int))
473 .ok_or_else(|| {
474 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
475 })?;
476 }
477 b'\x01' => {
478 self.buf = &self.buf[i + 1..];
479 return Ok(if negative { -value } else { value });
480 }
481 _ => {
482 return Err(self.reject(
483 self.current_tag,
484 ParseRejectReason::IncorrectDataFormatForValue,
485 ));
486 }
487 }
488 }
489
490 Err(DeserializeError::GarbledMessage(format!(
491 "no more data to parse tag {:?}",
492 self.current_tag
493 )))
494 }
495
496 pub fn deserialize_seq_num(&mut self) -> Result<SeqNum, DeserializeError> {
499 match self.buf {
500 [] => {
502 return Err(DeserializeError::GarbledMessage(format!(
503 "no more data to parse tag {:?}",
504 self.current_tag
505 )));
506 }
507 [b'\x01', ..] => return Err(DeserializeError::Logout),
508 _ => {}
509 }
510
511 let mut value: SeqNum = 0;
512 for i in 0..self.buf.len() {
513 match unsafe { self.buf.get_unchecked(i) } {
515 n @ b'0'..=b'9' => {
516 value = value
517 .checked_mul(10)
518 .and_then(|v| v.checked_add((n - b'0') as SeqNum))
519 .ok_or(DeserializeError::Logout)?;
520 }
521 b'\x01' => {
522 self.buf = &self.buf[i + 1..];
523 return Ok(value);
525 }
526 _ => return Err(DeserializeError::Logout),
527 }
528 }
529
530 Err(DeserializeError::GarbledMessage(format!(
531 "no more data to parse tag {:?}",
532 self.current_tag
533 )))
534 }
535
536 pub fn deserialize_num_in_group(&mut self) -> Result<NumInGroup, DeserializeError> {
539 match self.buf {
540 [] => {
542 return Err(DeserializeError::GarbledMessage(format!(
543 "no more data to parse tag {:?}",
544 self.current_tag
545 )));
546 }
547 [b'\x01', ..] => {
548 return Err(self.reject(
549 self.current_tag,
550 ParseRejectReason::TagSpecifiedWithoutAValue,
551 ));
552 }
553 _ => {}
554 }
555
556 let mut value: NumInGroup = 0;
557 for i in 0..self.buf.len() {
558 match unsafe { self.buf.get_unchecked(i) } {
560 n @ b'0'..=b'9' => {
561 value = value
562 .checked_mul(10)
563 .and_then(|v| v.checked_add((n - b'0') as NumInGroup))
564 .ok_or_else(|| {
565 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
566 })?;
567 }
568 b'\x01' => {
569 if value == 0 {
570 return Err(
571 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
572 );
573 } else {
574 self.buf = &self.buf[i + 1..];
575 return Ok(value);
576 }
577 }
578 _ => {
579 return Err(self.reject(
580 self.current_tag,
581 ParseRejectReason::IncorrectDataFormatForValue,
582 ));
583 }
584 }
585 }
586
587 Err(DeserializeError::GarbledMessage(format!(
588 "no more data to parse tag {:?}",
589 self.current_tag
590 )))
591 }
592
593 pub fn deserialize_day_of_month(&mut self) -> Result<DayOfMonth, DeserializeError> {
596 match self.buf {
597 [] => {
599 return Err(DeserializeError::GarbledMessage(format!(
600 "no more data to parse tag {:?}",
601 self.current_tag
602 )));
603 }
604 [b'\x01', ..] => {
605 return Err(self.reject(
606 self.current_tag,
607 ParseRejectReason::TagSpecifiedWithoutAValue,
608 ));
609 }
610 [b'0', ..] => {
611 return Err(self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect));
612 }
613 _ => {}
614 };
615
616 let mut value: NumInGroup = 0;
617 for i in 0..self.buf.len() {
618 match unsafe { self.buf.get_unchecked(i) } {
620 n @ b'0'..=b'9' => {
621 value = value
622 .checked_mul(10)
623 .and_then(|v| v.checked_add((n - b'0') as NumInGroup))
624 .ok_or_else(|| {
625 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
626 })?;
627 }
628 b'\x01' => {
629 self.buf = &self.buf[i + 1..];
630 break;
631 }
632 _ => {
633 return Err(self.reject(
634 self.current_tag,
635 ParseRejectReason::IncorrectDataFormatForValue,
636 ));
637 }
638 }
639 }
640
641 match value {
642 1..=31 => Ok(value),
643 _ => Err(self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)),
644 }
645 }
646
647 pub fn deserialize_float(&mut self) -> Result<Float, DeserializeError> {
659 let (negative, buf) = match self.buf {
660 [] => {
661 return Err(DeserializeError::GarbledMessage(format!(
662 "no more data to parse tag {:?}",
663 self.current_tag
664 )));
665 }
666 [b'\x01', ..] => {
667 return Err(self.reject(
668 self.current_tag,
669 ParseRejectReason::TagSpecifiedWithoutAValue,
670 ));
671 }
672 [b'-', b'\x01', ..] => {
673 return Err(self.reject(
674 self.current_tag,
675 ParseRejectReason::IncorrectDataFormatForValue,
676 ));
677 }
678 [b'-', buf @ ..] => (true, buf),
679 _ => (false, self.buf),
680 };
681
682 let mut num: i64 = 0;
683 let mut scale = None;
684 for i in 0..buf.len() {
685 match unsafe { buf.get_unchecked(i) } {
687 n @ b'0'..=b'9' => {
688 num = num
689 .checked_mul(10)
690 .and_then(|v| v.checked_add((n - b'0') as i64))
691 .ok_or_else(|| {
692 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
693 })?;
694 if let Some(scale) = scale.as_mut() {
695 *scale += 1;
696 }
697 }
698 b'.' => {
699 if scale.is_some() {
700 return Err(self.reject(
701 self.current_tag,
702 ParseRejectReason::IncorrectDataFormatForValue,
703 ));
704 }
705 scale = Some(0);
706 }
707 b'\x01' => {
708 self.buf = &self.buf[i + 1..];
709 let scale = scale.unwrap_or(0);
710 return Ok(Decimal::new(if negative { -num } else { num }, scale));
712 }
713 _ => {
714 return Err(self.reject(
715 self.current_tag,
716 ParseRejectReason::IncorrectDataFormatForValue,
717 ));
718 }
719 }
720 }
721
722 Err(DeserializeError::GarbledMessage(format!(
723 "no more data to parse tag {:?}",
724 self.current_tag
725 )))
726 }
727
728 #[inline(always)]
729 pub fn deserialize_qty(&mut self) -> Result<Qty, DeserializeError> {
730 self.deserialize_float()
731 }
732
733 #[inline(always)]
734 pub fn deserialize_price(&mut self) -> Result<Price, DeserializeError> {
735 self.deserialize_float()
736 }
737
738 #[inline(always)]
739 pub fn deserialize_price_offset(&mut self) -> Result<PriceOffset, DeserializeError> {
740 self.deserialize_float()
741 }
742
743 #[inline(always)]
744 pub fn deserialize_amt(&mut self) -> Result<Amt, DeserializeError> {
745 self.deserialize_float()
746 }
747
748 #[inline(always)]
749 pub fn deserialize_percentage(&mut self) -> Result<Percentage, DeserializeError> {
750 self.deserialize_float()
751 }
752
753 pub fn deserialize_boolean(&mut self) -> Result<Boolean, DeserializeError> {
754 match self.buf {
755 [] => Err(DeserializeError::GarbledMessage(format!(
757 "no more data to parse tag {:?}",
758 self.current_tag
759 ))),
760 [b'Y'] | [b'N'] => Err(DeserializeError::GarbledMessage(format!(
761 "missing tag ({:?}) separator",
762 self.current_tag
763 ))),
764 [b'\x01', ..] => Err(self.reject(
765 self.current_tag,
766 ParseRejectReason::TagSpecifiedWithoutAValue,
767 )),
768 [b'Y', b'\x01', buf @ ..] => {
769 self.buf = buf;
770 Ok(true)
771 }
772 [b'N', b'\x01', buf @ ..] => {
773 self.buf = buf;
774 Ok(false)
775 }
776 _ => Err(self.reject(
777 self.current_tag,
778 ParseRejectReason::IncorrectDataFormatForValue,
779 )),
780 }
781 }
782
783 pub fn deserialize_char(&mut self) -> Result<Char, DeserializeError> {
786 match self.buf {
787 [] => Err(DeserializeError::GarbledMessage(format!(
788 "no more data to parse tag {:?}",
789 self.current_tag
790 ))),
791 [b'\x01', ..] => Err(self.reject(
792 self.current_tag,
793 ParseRejectReason::TagSpecifiedWithoutAValue,
794 )),
795 [0x00..=0x1f | 0x80..=0xff, ..] => {
797 Err(self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect))
798 }
799 [n, b'\x01', buf @ ..] => {
800 self.buf = buf;
801 Ok(*n)
802 }
803 [_, byte] if *byte != b'\x01' => Err(DeserializeError::GarbledMessage(
805 "missing tag spearator".into(),
806 )),
807 _ => Err(self.reject(
808 self.current_tag,
809 ParseRejectReason::IncorrectDataFormatForValue,
810 )),
811 }
812 }
813
814 pub fn deserialize_multiple_char_value(
817 &mut self,
818 ) -> Result<MultipleCharValue, DeserializeError> {
819 match self.buf {
820 [] => {
821 return Err(DeserializeError::GarbledMessage(format!(
822 "no more data to parse tag {:?}",
823 self.current_tag
824 )));
825 }
826 [b'\x01', ..] => {
827 return Err(self.reject(
828 self.current_tag,
829 ParseRejectReason::TagSpecifiedWithoutAValue,
830 ));
831 }
832 _ => {}
833 }
834
835 for i in 0..self.buf.len() {
836 if let b'\x01' = unsafe { self.buf.get_unchecked(i) } {
838 let data = &self.buf[0..i];
839 self.buf = &self.buf[i + 1..];
841 let mut result = MultipleCharValue::with_capacity(data.len() / 2 + 1);
842 for chunk in data.chunks(2) {
843 match chunk {
844 [b' '] | [b' ', _] => {
845 return Err(self.reject(
846 self.current_tag,
847 ParseRejectReason::IncorrectDataFormatForValue,
848 ));
849 }
850 [0x00..=0x1f] | [0x80..=0xff] => {
855 return Err(
856 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
857 );
858 }
859 [n] | [n, b' '] => result.push(*n),
860 _ => {
861 return Err(self.reject(
862 self.current_tag,
863 ParseRejectReason::IncorrectDataFormatForValue,
864 ));
865 }
866 }
867 }
868 return Ok(result);
869 }
870 }
871
872 Err(DeserializeError::GarbledMessage(format!(
873 "no more data to parse tag {:?}",
874 self.current_tag
875 )))
876 }
877
878 pub fn deserialize_str(&mut self) -> Result<&FixStr, DeserializeError> {
881 match deserialize_str(self.buf) {
882 Ok((leftover, fix_str)) => {
883 self.buf = leftover;
884 Ok(fix_str)
885 }
886 Err(DeserializeErrorInternal::Incomplete) => Err(DeserializeError::GarbledMessage(
887 format!("no more data to parse tag {:?}", self.current_tag),
888 )),
889 Err(DeserializeErrorInternal::Error(reason)) => {
890 Err(self.reject(self.current_tag, reason))
891 }
892 }
893 }
894
895 #[inline(always)]
898 pub fn deserialize_string(&mut self) -> Result<FixString, DeserializeError> {
899 self.deserialize_str().map(FixString::from)
900 }
901
902 pub fn deserialize_multiple_string_value(
905 &mut self,
906 ) -> Result<MultipleStringValue, DeserializeError> {
907 match self.buf {
908 [] => {
909 return Err(DeserializeError::GarbledMessage(format!(
910 "no more data to parse tag {:?}",
911 self.current_tag
912 )));
913 }
914 [b'\x01', ..] => {
915 return Err(self.reject(
916 self.current_tag,
917 ParseRejectReason::TagSpecifiedWithoutAValue,
918 ));
919 }
920 _ => {}
921 }
922
923 for i in 0..self.buf.len() {
924 if let b'\x01' = unsafe { self.buf.get_unchecked(i) } {
926 let data = &self.buf[0..i];
927 self.buf = &self.buf[i + 1..];
929 const DEFAULT_CAPACITY: usize = 4;
930 let mut result = MultipleStringValue::with_capacity(DEFAULT_CAPACITY);
931 for part in data.split(|p| *p == b' ') {
932 let mut sub_result = Vec::with_capacity(part.len());
933 for byte in part {
934 match byte {
935 0x00..=0x1f | 0x80..=0xff => {
937 return Err(self.reject(
938 self.current_tag,
939 ParseRejectReason::ValueIsIncorrect,
940 ));
941 }
942 n => sub_result.push(*n),
943 }
944 }
945 result.push(unsafe { FixString::from_ascii_unchecked(sub_result) });
947 }
948 return Ok(result);
949 }
950 }
951
952 Err(DeserializeError::GarbledMessage(format!(
953 "no more data to parse tag {:?}",
954 self.current_tag
955 )))
956 }
957
958 pub fn deserialize_country(&mut self) -> Result<Country, DeserializeError> {
961 match self.buf {
962 [] => Err(DeserializeError::GarbledMessage(format!(
963 "no more data to parse tag {:?}",
964 self.current_tag
965 ))),
966 [b'\x01', ..] => Err(self.reject(
967 self.current_tag,
968 ParseRejectReason::TagSpecifiedWithoutAValue,
969 )),
970 [_, b'\x01', ..] => Err(self.reject(
971 self.current_tag,
972 ParseRejectReason::IncorrectDataFormatForValue,
973 )),
974 bytes @ [_, _, b'\x01', buf @ ..] => {
975 self.buf = buf;
976 Country::from_bytes(&bytes[0..2]).ok_or_else(|| {
977 self.reject(
978 self.current_tag,
979 ParseRejectReason::IncorrectDataFormatForValue,
980 )
981 })
982 }
983 &[a, b, c] if a != b'\x01' && b != b'\x01' && c != b'\x01' => {
987 Err(DeserializeError::GarbledMessage(format!(
988 "missing tag ({:?}) separator",
989 self.current_tag
990 )))
991 }
992 _ => Err(self.reject(
993 self.current_tag,
994 ParseRejectReason::IncorrectDataFormatForValue,
995 )),
996 }
997 }
998
999 pub fn deserialize_currency(&mut self) -> Result<Currency, DeserializeError> {
1002 match self.buf {
1003 [] => Err(DeserializeError::GarbledMessage(format!(
1004 "no more data to parse tag {:?}",
1005 self.current_tag
1006 ))),
1007 [b'\x01', ..] => Err(self.reject(
1008 self.current_tag,
1009 ParseRejectReason::TagSpecifiedWithoutAValue,
1010 )),
1011 bytes @ [_, _, _, b'\x01', buf @ ..] => {
1012 self.buf = buf;
1013 Currency::from_bytes(&bytes[0..3]).ok_or_else(|| {
1014 self.reject(
1015 self.current_tag,
1016 ParseRejectReason::IncorrectDataFormatForValue,
1017 )
1018 })
1019 }
1020 _ => Err(self.reject(
1021 self.current_tag,
1022 ParseRejectReason::IncorrectDataFormatForValue,
1023 )),
1024 }
1025 }
1026
1027 pub fn deserialize_exchange(&mut self) -> Result<Exchange, DeserializeError> {
1031 match self.buf {
1032 [] => Err(DeserializeError::GarbledMessage(format!(
1033 "no more data to parse tag {:?}",
1034 self.current_tag
1035 ))),
1036 [b'\x01', ..] => Err(self.reject(
1037 self.current_tag,
1038 ParseRejectReason::TagSpecifiedWithoutAValue,
1039 )),
1040 [a, b, c, d, b'\x01', buf @ ..] => {
1041 self.buf = buf;
1042 Ok([*a, *b, *c, *d])
1044 }
1045 _ => Err(self.reject(
1046 self.current_tag,
1047 ParseRejectReason::IncorrectDataFormatForValue,
1048 )),
1049 }
1050 }
1051
1052 pub fn deserialize_month_year(&mut self) -> Result<MonthYear, DeserializeError> {
1066 match self.buf {
1067 [] => Err(DeserializeError::GarbledMessage(format!(
1068 "no more data to parse tag {:?}",
1069 self.current_tag
1070 ))),
1071 [b'\x01', ..] => Err(self.reject(
1072 self.current_tag,
1073 ParseRejectReason::TagSpecifiedWithoutAValue,
1074 )),
1075 [a, b, c, d, e, f, g, h, b'\x01', buf @ ..] => {
1076 self.buf = buf;
1077 Ok([*a, *b, *c, *d, *e, *f, *g, *h].into())
1079 }
1080 _ => Err(self.reject(
1081 self.current_tag,
1082 ParseRejectReason::IncorrectDataFormatForValue,
1083 )),
1084 }
1085 }
1086
1087 pub fn deserialize_language(&mut self) -> Result<Language, DeserializeError> {
1090 match self.buf {
1091 [] => Err(DeserializeError::GarbledMessage(format!(
1092 "no more data to parse tag {:?}",
1093 self.current_tag
1094 ))),
1095 [b'\x01', ..] => Err(self.reject(
1096 self.current_tag,
1097 ParseRejectReason::TagSpecifiedWithoutAValue,
1098 )),
1099 [a, b, b'\x01', buf @ ..] => {
1100 self.buf = buf;
1101 Ok([*a, *b])
1102 }
1103 _ => Err(self.reject(
1104 self.current_tag,
1105 ParseRejectReason::IncorrectDataFormatForValue,
1106 )),
1107 }
1108 }
1109
1110 fn deserialize_fraction_of_second(&mut self) -> Result<(u32, u8), DeserializeError> {
1112 match self.buf {
1113 [] => {
1114 return Err(DeserializeError::GarbledMessage(format!(
1115 "no more data to parse tag {:?}",
1116 self.current_tag
1117 )));
1118 }
1119 [b'\x01', ..] => {
1120 self.buf = &self.buf[1..];
1121 return Ok((0, 0));
1122 }
1123 [b'.', ..] => self.buf = &self.buf[1..],
1125 _ => {
1126 return Err(self.reject(
1127 self.current_tag,
1128 ParseRejectReason::IncorrectDataFormatForValue,
1129 ));
1130 }
1131 }
1132
1133 let mut fraction_of_second: u64 = 0;
1134 for i in 0..self.buf.len() {
1135 match unsafe { self.buf.get_unchecked(i) } {
1137 n @ b'0'..=b'9' => {
1138 fraction_of_second = fraction_of_second
1139 .checked_mul(10)
1140 .and_then(|v| v.checked_add((n - b'0') as u64))
1141 .ok_or_else(|| {
1142 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1143 })?;
1144 }
1145 b'\x01' => {
1146 self.buf = &self.buf[i + 1..];
1147 let (multiplier, divider) = match i {
1148 3 => (1_000_000, 1),
1149 6 => (1_000, 1),
1150 9 => (1, 1),
1151 12 => (1, 1_000),
1154 _ => {
1155 return Err(self.reject(
1156 self.current_tag,
1157 ParseRejectReason::IncorrectDataFormatForValue,
1158 ));
1159 }
1160 };
1161 let adjusted_fraction_of_second = (fraction_of_second * multiplier / divider)
1162 .try_into()
1163 .map_err(|_| {
1164 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1165 });
1166 match adjusted_fraction_of_second {
1167 Ok(adjusted_fraction_of_second) => {
1168 return Ok((adjusted_fraction_of_second, i as u8));
1169 }
1170 Err(err) => return Err(err),
1171 }
1172 }
1173 _ => {
1174 return Err(self.reject(
1175 self.current_tag,
1176 ParseRejectReason::IncorrectDataFormatForValue,
1177 ));
1178 }
1179 }
1180 }
1181
1182 Err(self.reject(
1183 self.current_tag,
1184 ParseRejectReason::IncorrectDataFormatForValue,
1185 ))
1186 }
1187
1188 pub fn deserialize_utc_timestamp(&mut self) -> Result<UtcTimestamp, DeserializeError> {
1206 match self.buf {
1207 [] => Err(DeserializeError::GarbledMessage(format!(
1208 "no more data to parse tag {:?}",
1209 self.current_tag
1210 ))),
1211 [b'\x01', ..] => Err(self.reject(
1212 self.current_tag,
1213 ParseRejectReason::TagSpecifiedWithoutAValue,
1214 )),
1215 [_] => Err(DeserializeError::GarbledMessage(format!(
1217 "missing tag ({:?}) separator",
1218 self.current_tag
1219 ))),
1220 [
1221 y3 @ b'0'..=b'9',
1223 y2 @ b'0'..=b'9',
1224 y1 @ b'0'..=b'9',
1225 y0 @ b'0'..=b'9',
1226 m1 @ b'0'..=b'1',
1228 m0 @ b'0'..=b'9',
1229 d1 @ b'0'..=b'3',
1231 d0 @ b'0'..=b'9',
1232 b'-',
1233 h1 @ b'0'..=b'2',
1235 h0 @ b'0'..=b'9',
1236 b':',
1237 mm1 @ b'0'..=b'5',
1239 mm0 @ b'0'..=b'9',
1240 b':',
1241 s1 @ b'0'..=b'5',
1244 s0 @ b'0'..=b'9',
1245 ..,
1246 ] => {
1247 self.buf = &self.buf[17..];
1248 let year = (y3 - b'0') as i32 * 1000
1249 + (y2 - b'0') as i32 * 100
1250 + (y1 - b'0') as i32 * 10
1251 + (y0 - b'0') as i32;
1252 let month = (m1 - b'0') as u32 * 10 + (m0 - b'0') as u32;
1253 let day = (d1 - b'0') as u32 * 10 + (d0 - b'0') as u32;
1254 let naive_date = NaiveDate::from_ymd_opt(year, month, day).ok_or_else(|| {
1255 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1256 })?;
1257 let hour = (h1 - b'0') as u32 * 10 + (h0 - b'0') as u32;
1258 let min = (mm1 - b'0') as u32 * 10 + (mm0 - b'0') as u32;
1259 let sec = (s1 - b'0') as u32 * 10 + (s0 - b'0') as u32;
1260 let (fraction_of_second, precision) = self.deserialize_fraction_of_second()?;
1261 let naive_date_time = naive_date
1262 .and_hms_nano_opt(hour, min, sec, fraction_of_second)
1263 .ok_or_else(|| {
1264 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1265 })?;
1266 let timestamp = Utc.from_utc_datetime(&naive_date_time);
1267
1268 match precision {
1269 0 => Ok(UtcTimestamp::with_secs(timestamp)),
1270 3 => Ok(UtcTimestamp::with_millis(timestamp)),
1271 6 => Ok(UtcTimestamp::with_micros(timestamp)),
1272 9 => Ok(UtcTimestamp::with_nanos(timestamp)),
1273 12 => Ok(UtcTimestamp::with_nanos(timestamp)),
1276 _ => Err(self.reject(
1277 self.current_tag,
1278 ParseRejectReason::IncorrectDataFormatForValue,
1279 )),
1280 }
1281 }
1282 _ => Err(self.reject(
1283 self.current_tag,
1284 ParseRejectReason::IncorrectDataFormatForValue,
1285 )),
1286 }
1287 }
1288
1289 pub fn deserialize_utc_time_only(&mut self) -> Result<UtcTimeOnly, DeserializeError> {
1307 match self.buf {
1308 [] => Err(DeserializeError::GarbledMessage(format!(
1309 "no more data to parse tag {:?}",
1310 self.current_tag
1311 ))),
1312 [b'\x01', ..] => Err(self.reject(
1313 self.current_tag,
1314 ParseRejectReason::TagSpecifiedWithoutAValue,
1315 )),
1316 [
1317 h1 @ b'0'..=b'2',
1319 h0 @ b'0'..=b'9',
1320 b':',
1321 m1 @ b'0'..=b'5',
1323 m0 @ b'0'..=b'9',
1324 b':',
1325 s1 @ b'0'..=b'5',
1327 s0 @ b'0'..=b'9',
1328 b':',
1329 ..,
1330 ] => {
1331 let h = (h1 - b'0') * 10 + (h0 - b'0');
1332 let m = (m1 - b'0') * 10 + (m0 - b'0');
1333 let s = (s1 - b'0') * 10 + (s0 - b'0');
1334 self.buf = &self.buf[9..];
1335 let (ns, precision) = self.deserialize_fraction_of_second()?;
1336 let timestamp = NaiveTime::from_hms_nano_opt(h.into(), m.into(), s.into(), ns)
1337 .ok_or_else(|| {
1338 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1339 });
1340 match timestamp {
1341 Ok(timestamp) => {
1342 match precision {
1343 0 => Ok(UtcTimeOnly::with_secs(timestamp)),
1344 3 => Ok(UtcTimeOnly::with_millis(timestamp)),
1345 6 => Ok(UtcTimeOnly::with_micros(timestamp)),
1346 9 => Ok(UtcTimeOnly::with_nanos(timestamp)),
1347 12 => Ok(UtcTimeOnly::with_nanos(timestamp)),
1350 _ => Err(self.reject(
1351 self.current_tag,
1352 ParseRejectReason::IncorrectDataFormatForValue,
1353 )),
1354 }
1355 }
1356 Err(err) => Err(err),
1357 }
1358 }
1359 [
1361 h1 @ b'0'..=b'2',
1362 h0 @ b'0'..=b'9',
1363 b':',
1364 m1 @ b'0'..=b'5',
1365 m0 @ b'0'..=b'9',
1366 b':',
1367 b'6',
1368 b'0',
1369 b':',
1370 ] => {
1371 let h = (h1 - b'0') * 10 + (h0 - b'0');
1372 let m = (m1 - b'0') * 10 + (m0 - b'0');
1373 let s = 60;
1374 self.buf = &self.buf[9..];
1375 let (ns, precision) = self.deserialize_fraction_of_second()?;
1376 let timestamp =
1377 NaiveTime::from_hms_nano_opt(h.into(), m.into(), s, ns).ok_or_else(|| {
1378 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1379 });
1380 match timestamp {
1381 Ok(timestamp) => {
1382 match precision {
1383 0 => Ok(UtcTimeOnly::with_secs(timestamp)),
1384 3 => Ok(UtcTimeOnly::with_millis(timestamp)),
1385 6 => Ok(UtcTimeOnly::with_micros(timestamp)),
1386 9 => Ok(UtcTimeOnly::with_nanos(timestamp)),
1387 12 => Ok(UtcTimeOnly::with_nanos(timestamp)),
1390 _ => Err(self.reject(
1391 self.current_tag,
1392 ParseRejectReason::IncorrectDataFormatForValue,
1393 )),
1394 }
1395 }
1396 Err(err) => Err(err),
1397 }
1398 }
1399 _ => Err(self.reject(
1400 self.current_tag,
1401 ParseRejectReason::IncorrectDataFormatForValue,
1402 )),
1403 }
1404 }
1405
1406 pub fn deserialize_utc_date_only(&mut self) -> Result<UtcDateOnly, DeserializeError> {
1414 match self.buf {
1415 [] => Err(DeserializeError::GarbledMessage(format!(
1416 "no more data to parse tag {:?}",
1417 self.current_tag
1418 ))),
1419 [b'\x01', ..] => Err(self.reject(
1420 self.current_tag,
1421 ParseRejectReason::TagSpecifiedWithoutAValue,
1422 )),
1423 [_] => Err(DeserializeError::GarbledMessage(format!(
1425 "missing tag ({:?}) separator",
1426 self.current_tag
1427 ))),
1428 [
1429 y3 @ b'0'..=b'9',
1431 y2 @ b'0'..=b'9',
1432 y1 @ b'0'..=b'9',
1433 y0 @ b'0'..=b'9',
1434 m1 @ b'0'..=b'1',
1436 m0 @ b'0'..=b'9',
1437 d1 @ b'0'..=b'3',
1439 d0 @ b'0'..=b'9',
1440 b'\x01',
1442 ] => {
1443 let year = (y3 - b'0') as u16 * 1000
1444 + (y2 - b'0') as u16 * 100
1445 + (y1 - b'0') as u16 * 10
1446 + (y0 - b'0') as u16;
1447 let month = (m1 - b'0') * 10 + (m0 - b'0');
1448 let day = (d1 - b'0') * 10 + (d0 - b'0');
1449 self.buf = &self.buf[9..];
1450 UtcDateOnly::from_ymd_opt(year.into(), month.into(), day.into()).ok_or_else(|| {
1451 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1452 })
1453 }
1454 _ => Err(self.reject(
1455 self.current_tag,
1456 ParseRejectReason::IncorrectDataFormatForValue,
1457 )),
1458 }
1459 }
1460
1461 pub fn deserialize_local_mkt_time(&mut self) -> Result<LocalMktTime, DeserializeError> {
1472 match self.buf {
1473 [] => Err(DeserializeError::GarbledMessage(format!(
1474 "no more data to parse tag {:?}",
1475 self.current_tag
1476 ))),
1477 [b'\x01', ..] => Err(self.reject(
1478 self.current_tag,
1479 ParseRejectReason::TagSpecifiedWithoutAValue,
1480 )),
1481 [_] => Err(DeserializeError::GarbledMessage(format!(
1483 "missing tag ({:?}) separator",
1484 self.current_tag
1485 ))),
1486
1487 [
1488 h1 @ b'0'..=b'2',
1490 h0 @ b'0'..=b'9',
1491 b':',
1492 m1 @ b'0'..=b'5',
1494 m0 @ b'0'..=b'0',
1495 b':',
1496 s1 @ b'0'..=b'5',
1498 s0 @ b'0'..=b'9',
1499 b'\x01',
1500 ..,
1501 ] => {
1502 let hour = (h1 - b'0') as u32 * 10 + (h0 - b'0') as u32;
1503 let minute = (m1 - b'0') as u32 * 10 + (m0 - b'0') as u32;
1504 let second = (s1 - b'0') as u32 * 10 + (s0 - b'0') as u32;
1505 self.buf = &self.buf[8..];
1506 LocalMktTime::from_hms_opt(hour, minute, second).ok_or_else(|| {
1507 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1508 })
1509 }
1510 _ => Err(self.reject(
1511 self.current_tag,
1512 ParseRejectReason::IncorrectDataFormatForValue,
1513 )),
1514 }
1515 }
1516
1517 pub fn deserialize_local_mkt_date(&mut self) -> Result<LocalMktDate, DeserializeError> {
1525 match self.buf {
1526 [] => Err(DeserializeError::GarbledMessage(format!(
1527 "no more data to parse tag {:?}",
1528 self.current_tag
1529 ))),
1530 [b'\x01', ..] => Err(self.reject(
1531 self.current_tag,
1532 ParseRejectReason::TagSpecifiedWithoutAValue,
1533 )),
1534 [_] => Err(DeserializeError::GarbledMessage(format!(
1536 "missing tag ({:?}) separator",
1537 self.current_tag
1538 ))),
1539 [
1540 y3 @ b'0'..=b'9',
1542 y2 @ b'0'..=b'9',
1543 y1 @ b'0'..=b'9',
1544 y0 @ b'0'..=b'9',
1545 m1 @ b'0'..=b'1',
1547 m0 @ b'0'..=b'9',
1548 d1 @ b'0'..=b'3',
1550 d0 @ b'0'..=b'9',
1551 b'\x01',
1553 ..,
1554 ] => {
1555 let year = (y3 - b'0') as u16 * 1000
1556 + (y2 - b'0') as u16 * 100
1557 + (y1 - b'0') as u16 * 10
1558 + (y0 - b'0') as u16;
1559 let month = (m1 - b'0') * 10 + (m0 - b'0');
1560 let day = (d1 - b'0') * 10 + (d0 - b'0');
1561 self.buf = &self.buf[9..];
1562 LocalMktDate::from_ymd_opt(year.into(), month.into(), day.into()).ok_or_else(|| {
1563 self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect)
1564 })
1565 }
1566 _ => Err(self.reject(
1567 self.current_tag,
1568 ParseRejectReason::IncorrectDataFormatForValue,
1569 )),
1570 }
1571 }
1572
1573 pub fn deserialize_tz_timestamp(&mut self) -> Result<TzTimestamp, DeserializeError> {
1593 match self.buf {
1594 [] => {
1595 return Err(DeserializeError::GarbledMessage(format!(
1596 "no more data to parse tag {:?}",
1597 self.current_tag
1598 )));
1599 }
1600 [b'\x01', ..] => {
1601 return Err(self.reject(
1602 self.current_tag,
1603 ParseRejectReason::TagSpecifiedWithoutAValue,
1604 ));
1605 }
1606 [_] => {
1608 return Err(DeserializeError::GarbledMessage(format!(
1609 "missing tag ({:?}) separator",
1610 self.current_tag
1611 )));
1612 }
1613 _ => {}
1614 }
1615 for i in 0..self.buf.len() {
1616 if let b'\x01' = unsafe { self.buf.get_unchecked(i) } {
1618 let data = &self.buf[0..i - 1];
1620 self.buf = &self.buf[i + 1..];
1621 return Ok(data.into());
1623 }
1624 }
1625
1626 Err(DeserializeError::GarbledMessage(format!(
1627 "no more data to parse tag {:?}",
1628 self.current_tag
1629 )))
1630 }
1631
1632 pub fn deserialize_tz_timeonly(&mut self) -> Result<TzTimeOnly, DeserializeError> {
1643 match self.buf {
1644 [] => {
1645 return Err(DeserializeError::GarbledMessage(format!(
1646 "no more data to parse tag {:?}",
1647 self.current_tag
1648 )));
1649 }
1650 &[b'\x01', ..] => {
1651 return Err(self.reject(
1652 self.current_tag,
1653 ParseRejectReason::TagSpecifiedWithoutAValue,
1654 ));
1655 }
1656 &[_] => {
1658 return Err(DeserializeError::GarbledMessage(format!(
1659 "missing tag ({:?}) separator",
1660 self.current_tag
1661 )));
1662 }
1663 _ => {}
1664 }
1665 for i in 0..self.buf.len() {
1666 if let b'\x01' = unsafe { self.buf.get_unchecked(i) } {
1668 let data = &self.buf[0..i - 1];
1670 self.buf = &self.buf[i + 1..];
1671 return Ok(data.into());
1672 }
1673 }
1674
1675 Err(DeserializeError::GarbledMessage(format!(
1676 "no more data to parse tag {:?}",
1677 self.current_tag
1678 )))
1679 }
1680
1681 pub fn deserialize_length(&mut self) -> Result<Length, DeserializeError> {
1691 match deserialize_length(self.buf) {
1692 Ok((leftover, len)) => {
1693 self.buf = leftover;
1694 Ok(len)
1695 }
1696 Err(DeserializeErrorInternal::Incomplete) => Err(DeserializeError::GarbledMessage(
1697 format!("no more data to parse tag {:?}", self.current_tag),
1698 )),
1699 Err(DeserializeErrorInternal::Error(reject)) => {
1700 Err(self.reject(self.current_tag, reject))
1701 }
1702 }
1703 }
1704
1705 pub fn deserialize_data(&mut self, len: usize) -> Result<Data, DeserializeError> {
1711 if self.buf.is_empty() {
1712 return Err(DeserializeError::GarbledMessage(format!(
1713 "no more data to parse tag {:?}",
1714 self.current_tag
1715 )));
1716 }
1717
1718 if self.buf.len() < len + 1 {
1720 return Err(DeserializeError::GarbledMessage(format!(
1721 "no more data to parse tag {:?}",
1722 self.current_tag
1723 )));
1724 }
1725
1726 if let b'\x01' = unsafe { *self.buf.get_unchecked(len + 1) } {
1728 return Err(DeserializeError::GarbledMessage(format!(
1730 "missing tag ({:?}) separator",
1731 self.current_tag
1732 )));
1733 }
1734
1735 let data = &self.buf[0..len];
1736 self.buf = &self.buf[len + 1..];
1738 Ok(data.into())
1739 }
1740
1741 pub fn deserialize_xml(&mut self, len: usize) -> Result<XmlData, DeserializeError> {
1752 match self.buf {
1753 [] => {
1754 return Err(DeserializeError::GarbledMessage(format!(
1755 "no more data to parse tag {:?}",
1756 self.current_tag
1757 )));
1758 }
1759 [b'\x01', ..] => {
1760 return Err(self.reject(
1761 self.current_tag,
1762 ParseRejectReason::TagSpecifiedWithoutAValue,
1763 ));
1764 }
1765 _ => {}
1766 }
1767
1768 if self.buf.len() < len + 1 {
1770 return Err(DeserializeError::GarbledMessage(format!(
1771 "no more data to parse tag {:?}",
1772 self.current_tag
1773 )));
1774 }
1775
1776 if let b'\x01' = unsafe { *self.buf.get_unchecked(len + 1) } {
1778 return Err(DeserializeError::GarbledMessage(format!(
1780 "missing tag ({:?}) separator",
1781 self.current_tag
1782 )));
1783 }
1784
1785 let xml = &self.buf[0..len];
1787 self.buf = &self.buf[len + 1..];
1789 Ok(xml.into())
1790 }
1791
1792 pub fn deserialize_int_enum<T>(&mut self) -> Result<T, DeserializeError>
1798 where
1799 T: TryFrom<Int, Error = ParseRejectReason>,
1800 {
1801 T::try_from(self.deserialize_int()?).map_err(|reason| self.reject(self.current_tag, reason))
1802 }
1803
1804 pub fn deserialize_num_in_group_enum<T>(&mut self) -> Result<T, DeserializeError>
1805 where
1806 T: TryFrom<NumInGroup, Error = ParseRejectReason>,
1807 {
1808 T::try_from(self.deserialize_num_in_group()?)
1809 .map_err(|reason| self.reject(self.current_tag, reason))
1810 }
1811
1812 pub fn deserialize_char_enum<T>(&mut self) -> Result<T, DeserializeError>
1813 where
1814 T: TryFrom<Char, Error = ParseRejectReason>,
1815 {
1816 let value = self.deserialize_char()?;
1817 T::try_from(value).map_err(|reason| self.reject(self.current_tag, reason))
1818 }
1819
1820 pub fn deserialize_string_enum<T>(&mut self) -> Result<T, DeserializeError>
1821 where
1822 for<'a> T: TryFrom<&'a FixStr, Error = ParseRejectReason>,
1823 {
1824 let value = self.deserialize_str()?;
1825 T::try_from(value).map_err(|reason| self.reject(self.current_tag, reason))
1826 }
1827
1828 pub fn deserialize_multiple_char_value_enum<T>(&mut self) -> Result<Vec<T>, DeserializeError>
1829 where
1830 T: TryFrom<Char, Error = ParseRejectReason>,
1831 {
1832 let values = self.deserialize_multiple_char_value()?;
1833 let mut result = Vec::with_capacity(values.len());
1834 for value in values {
1835 result
1836 .push(T::try_from(value).map_err(|reason| self.reject(self.current_tag, reason))?);
1837 }
1838 Ok(result)
1839 }
1840
1841 pub fn deserialize_multiple_string_value_enum<T>(&mut self) -> Result<Vec<T>, DeserializeError>
1842 where
1843 for<'a> T: TryFrom<&'a FixStr, Error = ParseRejectReason>,
1844 {
1845 let values = self.deserialize_multiple_string_value()?;
1846 let mut result = Vec::with_capacity(values.len());
1847 for value in values {
1848 result
1849 .push(T::try_from(&value).map_err(|reason| self.reject(self.current_tag, reason))?);
1850 }
1851 Ok(result)
1852 }
1853}
1854
1855#[cfg(test)]
1856mod tests {
1857 use std::str::FromStr;
1858
1859 use assert_matches::assert_matches;
1860 use chrono::{DateTime, NaiveDate, NaiveTime, TimeZone, Utc};
1861
1862 use super::{Deserializer, RawMessage, deserialize_tag, raw_message};
1863 use crate::{
1864 deserializer::{RawMessageError, deserialize_checksum},
1865 fields::{LocalMktDate, Price, TimePrecision},
1866 messages::BEGIN_STRING,
1867 };
1868
1869 #[test]
1870 fn deserialize_tag_ok() {
1871 assert_matches!(deserialize_tag(b"8=FIXT1.1\x01", b"8="), Ok(b"FIXT1.1\x01"));
1872 }
1873
1874 #[test]
1875 fn deserialize_tag_incomplete() {
1876 assert_matches!(
1877 deserialize_tag(b"", b"8="),
1878 Err(RawMessageError::Incomplete)
1879 );
1880
1881 assert_matches!(
1882 deserialize_tag(b"8", b"8="),
1883 Err(RawMessageError::Incomplete)
1884 );
1885 }
1886
1887 #[test]
1888 fn deserialize_tag_garbled() {
1889 assert_matches!(
1890 deserialize_tag(b"89FIXT1.1\x01", b"8="),
1891 Err(RawMessageError::Garbled)
1892 );
1893 }
1894
1895 #[test]
1896 fn deserialize_checksum_ok() {
1897 assert_matches!(deserialize_checksum(b"123\x01"), Ok((b"", 123)));
1898
1899 assert_matches!(
1900 deserialize_checksum(b"123\x01more data"),
1901 Ok((b"more data", 123))
1902 );
1903 }
1904
1905 #[test]
1906 fn deserialize_checksum_incomplete() {
1907 assert_matches!(deserialize_checksum(b"1"), Err(RawMessageError::Incomplete));
1908
1909 assert_matches!(
1910 deserialize_checksum(b"12"),
1911 Err(RawMessageError::Incomplete)
1912 );
1913
1914 assert_matches!(
1915 deserialize_checksum(b"123"),
1916 Err(RawMessageError::Incomplete)
1917 );
1918 }
1919
1920 #[test]
1921 fn deserialize_checksum_garbled() {
1922 assert_matches!(
1923 deserialize_checksum(b"A23\x01"),
1924 Err(RawMessageError::InvalidChecksum)
1925 );
1926
1927 assert_matches!(
1928 deserialize_checksum(b"1234"),
1929 Err(RawMessageError::InvalidChecksum)
1930 );
1931 assert_matches!(
1932 deserialize_checksum(b"1234\x01"),
1933 Err(RawMessageError::InvalidChecksum)
1934 );
1935 }
1936
1937 #[test]
1938 fn raw_message_ok() {
1939 let input = b"8=MSG_BODY\x019=19\x01<lots of tags here>10=143\x01";
1940 assert!(raw_message(input).is_ok());
1941 }
1942
1943 #[test]
1944 fn raw_message_from_chunks_ok() {
1945 let input = &[
1946 b"8=MSG_BOD".as_slice(),
1947 b"Y\x019=19\x01<lots".as_slice(),
1948 b" of tags here>10=143\x01".as_slice(),
1949 b"leftover".as_slice(),
1950 ];
1951 let mut buf = Vec::new();
1952 let mut i = input.iter();
1953 {
1954 buf.extend_from_slice(i.next().unwrap());
1955 assert!(matches!(
1956 raw_message(&buf),
1957 Err(RawMessageError::Incomplete)
1958 ));
1959 }
1960 {
1961 buf.extend_from_slice(i.next().unwrap());
1962 assert!(matches!(
1963 raw_message(&buf),
1964 Err(RawMessageError::Incomplete)
1965 ));
1966 }
1967 {
1968 buf.extend_from_slice(i.next().unwrap());
1969 assert!(matches!(raw_message(&buf), Ok(([], _))));
1970 }
1971 {
1972 buf.extend_from_slice(i.next().unwrap());
1973 assert!(matches!(raw_message(&buf), Ok((b"leftover", _))));
1974 }
1975 }
1976
1977 fn deserializer(body: &[u8]) -> Deserializer {
1978 let raw_message = RawMessage {
1979 begin_string: BEGIN_STRING,
1980 body,
1981 checksum: 0,
1982 };
1983
1984 Deserializer {
1985 raw_message,
1986 buf: body,
1987 msg_type: None,
1988 seq_num: Some(1),
1989 current_tag: None,
1990 tmp_tag: None,
1991 }
1992 }
1993
1994 #[test]
1995 fn deserialize_str_ok() {
1996 let input = b"lorem ipsum\x01\x00";
1997 let mut deserializer = deserializer(input);
1998 let buf = deserializer
1999 .deserialize_str()
2000 .expect("failed to deserialize utc timestamp");
2001 assert_eq!(buf, "lorem ipsum");
2002 assert_eq!(deserializer.buf, &[b'\x00']);
2003 }
2004
2005 #[test]
2006 fn deserialize_string_ok() {
2007 let input = b"lorem ipsum\x01\x00";
2008 let mut deserializer = deserializer(input);
2009 let buf = deserializer
2010 .deserialize_string()
2011 .expect("failed to deserialize utc timestamp");
2012 assert_eq!(buf, "lorem ipsum");
2013 assert_eq!(deserializer.buf, &[b'\x00']);
2014 }
2015
2016 #[test]
2017 fn deserialize_utc_timestamp_ok() {
2018 let input = b"20190605-11:51:27\x01\x00";
2019 let mut deserializer = deserializer(input);
2020 let utc_timestamp = deserializer
2021 .deserialize_utc_timestamp()
2022 .expect("failed to deserialize utc timestamp");
2023 let date_time: DateTime<Utc> = Utc.from_utc_datetime(
2024 &NaiveDate::from_ymd_opt(2019, 6, 5)
2025 .unwrap()
2026 .and_hms_opt(11, 51, 27)
2027 .unwrap(),
2028 );
2029 assert_eq!(utc_timestamp.timestamp(), date_time);
2030 assert_eq!(utc_timestamp.precision(), TimePrecision::Secs);
2031 assert_eq!(deserializer.buf, &[b'\x00']);
2032 }
2033
2034 #[test]
2035 fn deserialize_utc_timestamp_with_millis_ok() {
2036 let input = b"20190605-11:51:27.848\x01\x00";
2037 let mut deserializer = deserializer(input);
2038 let utc_timestamp = deserializer
2039 .deserialize_utc_timestamp()
2040 .expect("failed to deserialize utc timestamp");
2041 let date_time = Utc.from_utc_datetime(
2042 &NaiveDate::from_ymd_opt(2019, 6, 5)
2043 .unwrap()
2044 .and_hms_milli_opt(11, 51, 27, 848)
2045 .unwrap(),
2046 );
2047 assert_eq!(utc_timestamp.timestamp(), date_time);
2048 assert_eq!(utc_timestamp.precision(), TimePrecision::Millis);
2049 assert_eq!(deserializer.buf, &[b'\x00']);
2050 }
2051
2052 #[test]
2053 fn deserialize_utc_timestamp_with_micros_ok() {
2054 let input = b"20190605-11:51:27.848757\x01\x00";
2055 let mut deserializer = deserializer(input);
2056 let utc_timestamp = deserializer
2057 .deserialize_utc_timestamp()
2058 .expect("failed to deserialize utc timestamp");
2059 let date_time = Utc.from_utc_datetime(
2060 &NaiveDate::from_ymd_opt(2019, 6, 5)
2061 .unwrap()
2062 .and_hms_micro_opt(11, 51, 27, 848757)
2063 .unwrap(),
2064 );
2065 assert_eq!(utc_timestamp.timestamp(), date_time);
2066 assert_eq!(utc_timestamp.precision(), TimePrecision::Micros);
2067 assert_eq!(deserializer.buf, &[b'\x00']);
2068 }
2069
2070 #[test]
2071 fn deserialize_utc_timestamp_with_nanos_ok() {
2072 let input = b"20190605-11:51:27.848757123\x01\x00";
2073 let mut deserializer = deserializer(input);
2074 let utc_timestamp = deserializer
2075 .deserialize_utc_timestamp()
2076 .expect("failed to deserialize utc timestamp");
2077 let date_time = Utc.from_utc_datetime(
2078 &NaiveDate::from_ymd_opt(2019, 6, 5)
2079 .unwrap()
2080 .and_hms_nano_opt(11, 51, 27, 848757123)
2081 .unwrap(),
2082 );
2083 assert_eq!(utc_timestamp.timestamp(), date_time);
2084 assert_eq!(utc_timestamp.precision(), TimePrecision::Nanos);
2085 assert_eq!(deserializer.buf, &[b'\x00']);
2086 }
2087
2088 #[test]
2089 fn deserialize_utc_timestamp_with_picos_ok() {
2090 let input = b"20190605-11:51:27.848757123999\x01\x00";
2091 let mut deserializer = deserializer(input);
2092 let utc_timestamp = deserializer
2093 .deserialize_utc_timestamp()
2094 .expect("failed to deserialize utc timestamp");
2095 let date_time = Utc.from_utc_datetime(
2096 &NaiveDate::from_ymd_opt(2019, 6, 5)
2097 .unwrap()
2098 .and_hms_nano_opt(11, 51, 27, 848757123)
2099 .unwrap(),
2100 );
2101 assert_eq!(utc_timestamp.timestamp(), date_time);
2102 assert_eq!(utc_timestamp.precision(), TimePrecision::Nanos);
2103 assert_eq!(deserializer.buf, &[b'\x00']);
2104 }
2105
2106 #[ignore]
2108 #[test]
2109 fn deserialize_utc_timeonly_ok() {
2110 let input = b"11:51:27\x01\x00";
2111 let mut deserializer = deserializer(input);
2112 let utc_timeonly = deserializer
2113 .deserialize_utc_time_only()
2114 .expect("failed to deserialize utc timeonly");
2115 let time: NaiveTime = NaiveTime::from_hms_opt(11, 51, 27).unwrap();
2116 assert_eq!(utc_timeonly.timestamp(), time);
2117 assert_eq!(utc_timeonly.precision(), TimePrecision::Secs);
2118 assert_eq!(deserializer.buf, &[b'\x00']);
2119 }
2120
2121 #[test]
2122 fn deserialize_local_mkt_date_ok() {
2123 let input = b"20220530\x01\x00";
2124 let mut deserializer = deserializer(input);
2125 let local_mkt_date = deserializer
2126 .deserialize_local_mkt_date()
2127 .expect("failed to deserialize utc timestamp");
2128 assert_eq!(
2129 local_mkt_date,
2130 LocalMktDate::from_ymd_opt(2022, 5, 30).unwrap()
2131 );
2132 assert_eq!(deserializer.buf, &[b'\x00']);
2133 }
2134
2135 #[test]
2136 fn deserialize_price_ok() {
2137 let values: &[(&[u8], Price)] = &[
2138 (b"97\x01\x00", Price::from_str("97").expect("Wrong decimal")),
2139 (
2140 b"97.\x01\x00",
2141 Price::from_str("97.").expect("Wrong decimal"),
2142 ),
2143 (
2144 b"97.0347\x01\x00",
2145 Price::from_str("97.0347").expect("Wrong decimal"),
2146 ),
2147 ];
2148 for (input, value) in values {
2149 let mut deserializer = deserializer(input);
2150 let price = deserializer
2151 .deserialize_price()
2152 .expect("failed to deserialize price");
2153 assert_eq!(price, *value);
2154 assert_eq!(deserializer.buf, &[b'\x00']);
2155 }
2156 }
2157}