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 [] => {
1208 Err(DeserializeError::GarbledMessage(format!(
1209 "no more data to parse tag {:?}",
1210 self.current_tag
1211 )))
1212 }
1213 [b'\x01', ..] => {
1214 Err(self.reject(self.current_tag, ParseRejectReason::TagSpecifiedWithoutAValue))
1215 }
1216 [_] => Err(DeserializeError::GarbledMessage(format!(
1218 "missing tag ({:?}) separator",
1219 self.current_tag
1220 ))),
1221 [
1222 y3 @ b'0'..=b'9', y2 @ b'0'..=b'9', y1 @ b'0'..=b'9', y0 @ b'0'..=b'9',
1224 m1 @ b'0'..=b'1', m0 @ b'0'..=b'9',
1226 d1 @ b'0'..=b'3', d0 @ b'0'..=b'9',
1228 b'-',
1229 h1 @ b'0'..=b'2', h0 @ b'0'..=b'9',
1231 b':',
1232 mm1 @ b'0'..=b'5', mm0 @ b'0'..=b'9',
1234 b':',
1235 s1 @ b'0'..=b'5', s0 @ b'0'..=b'9',
1238 ..
1239 ] => {
1240 self.buf = &self.buf[17..];
1241 let year = (y3 - b'0') as i32 * 1000
1242 + (y2 - b'0') as i32 * 100
1243 + (y1 - b'0') as i32 * 10
1244 + (y0 - b'0') as i32;
1245 let month = (m1 - b'0') as u32 * 10 + (m0 - b'0') as u32;
1246 let day = (d1 - b'0') as u32 * 10 + (d0 - b'0') as u32;
1247 let naive_date = NaiveDate::from_ymd_opt(year, month, day)
1248 .ok_or_else(|| self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect))?;
1249 let hour = (h1 - b'0') as u32 * 10 + (h0 - b'0') as u32;
1250 let min = (mm1 - b'0') as u32 * 10 + (mm0 - b'0') as u32;
1251 let sec = (s1 - b'0') as u32 * 10 + (s0 - b'0') as u32;
1252 let (fraction_of_second, precision) = self.deserialize_fraction_of_second()?;
1253 let naive_date_time = naive_date
1254 .and_hms_nano_opt(hour, min, sec, fraction_of_second)
1255 .ok_or_else(|| self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect))?;
1256 let timestamp = Utc.from_utc_datetime(&naive_date_time);
1257
1258 match precision {
1259 0 => Ok(UtcTimestamp::with_secs(timestamp)),
1260 3 => Ok(UtcTimestamp::with_millis(timestamp)),
1261 6 => Ok(UtcTimestamp::with_micros(timestamp)),
1262 9 => Ok(UtcTimestamp::with_nanos(timestamp)),
1263 12 => Ok(UtcTimestamp::with_nanos(timestamp)),
1266 _ => Err(self.reject(self.current_tag, ParseRejectReason::IncorrectDataFormatForValue)),
1267 }
1268 }
1269 _ => Err(self.reject(self.current_tag, ParseRejectReason::IncorrectDataFormatForValue)),
1270 }
1271 }
1272
1273 pub fn deserialize_utc_time_only(&mut self) -> Result<UtcTimeOnly, DeserializeError> {
1291 match self.buf {
1292 [] => {
1293 Err(DeserializeError::GarbledMessage(format!(
1294 "no more data to parse tag {:?}",
1295 self.current_tag
1296 )))
1297 }
1298 [b'\x01', ..] => {
1299 Err(self.reject(
1300 self.current_tag,
1301 ParseRejectReason::TagSpecifiedWithoutAValue,
1302 ))
1303 }
1304 [
1305 h1 @ b'0'..=b'2', h0 @ b'0'..=b'9', b':',
1307 m1 @ b'0'..=b'5', m0 @ b'0'..=b'9', b':',
1309 s1 @ b'0'..=b'5', s0 @ b'0'..=b'9', b':',
1311 ..
1312 ] =>
1313 {
1314 let h = (h1 - b'0') * 10 + (h0 - b'0');
1315 let m = (m1 - b'0') * 10 + (m0 - b'0');
1316 let s = (s1 - b'0') * 10 + (s0 - b'0');
1317 self.buf = &self.buf[9..];
1318 let (ns, precision) = self.deserialize_fraction_of_second()?;
1319 let timestamp = NaiveTime::from_hms_nano_opt(h.into(), m.into(), s.into(), ns)
1320 .ok_or_else(|| self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect));
1321 match timestamp {
1322 Ok(timestamp) => {
1323 match precision {
1324 0 => Ok(UtcTimeOnly::with_secs(timestamp)),
1325 3 => Ok(UtcTimeOnly::with_millis(timestamp)),
1326 6 => Ok(UtcTimeOnly::with_micros(timestamp)),
1327 9 => Ok(UtcTimeOnly::with_nanos(timestamp)),
1328 12 => Ok(UtcTimeOnly::with_nanos(timestamp)),
1331 _ => Err(self.reject(self.current_tag, ParseRejectReason::IncorrectDataFormatForValue)),
1332 }
1333 },
1334 Err(err) => Err(err)
1335 }
1336 }
1337 [h1 @ b'0'..=b'2', h0 @ b'0'..=b'9', b':', m1 @ b'0'..=b'5', m0 @ b'0'..=b'9', b':', b'6', b'0', b':'] =>
1339 {
1340 let h = (h1 - b'0') * 10 + (h0 - b'0');
1341 let m = (m1 - b'0') * 10 + (m0 - b'0');
1342 let s = 60;
1343 self.buf = &self.buf[9..];
1344 let (ns, precision) = self.deserialize_fraction_of_second()?;
1345 let timestamp = NaiveTime::from_hms_nano_opt(h.into(), m.into(), s, ns)
1346 .ok_or_else(|| self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect));
1347 match timestamp {
1348 Ok(timestamp) => {
1349 match precision {
1350 0 => Ok(UtcTimeOnly::with_secs(timestamp)),
1351 3 => Ok(UtcTimeOnly::with_millis(timestamp)),
1352 6 => Ok(UtcTimeOnly::with_micros(timestamp)),
1353 9 => Ok(UtcTimeOnly::with_nanos(timestamp)),
1354 12 => Ok(UtcTimeOnly::with_nanos(timestamp)),
1357 _ => Err(self.reject(self.current_tag, ParseRejectReason::IncorrectDataFormatForValue)),
1358 }
1359 },
1360 Err(err) => Err(err)
1361 }
1362 }
1363 _ => Err(self.reject(self.current_tag, ParseRejectReason::IncorrectDataFormatForValue)),
1364 }
1365 }
1366
1367 pub fn deserialize_utc_date_only(&mut self) -> Result<UtcDateOnly, DeserializeError> {
1375 match self.buf {
1376 [] => {
1377 Err(DeserializeError::GarbledMessage(format!(
1378 "no more data to parse tag {:?}",
1379 self.current_tag
1380 )))
1381 }
1382 [b'\x01', ..] => Err(self.reject(self.current_tag, ParseRejectReason::TagSpecifiedWithoutAValue)),
1383 [_] => Err(DeserializeError::GarbledMessage(format!(
1385 "missing tag ({:?}) separator",
1386 self.current_tag
1387 ))),
1388 [
1389 y3 @ b'0'..=b'9', y2 @ b'0'..=b'9', y1 @ b'0'..=b'9', y0 @ b'0'..=b'9',
1391 m1 @ b'0'..=b'1', m0 @ b'0'..=b'9',
1393 d1 @ b'0'..=b'3', d0 @ b'0'..=b'9',
1395 b'\x01',
1397 ] => {
1398 let year = (y3 - b'0') as u16 * 1000
1399 + (y2 - b'0') as u16 * 100
1400 + (y1 - b'0') as u16 * 10
1401 + (y0 - b'0') as u16;
1402 let month = (m1 - b'0') * 10 + (m0 - b'0');
1403 let day = (d1 - b'0') * 10 + (d0 - b'0');
1404 self.buf = &self.buf[9..];
1405 UtcDateOnly::from_ymd_opt(year.into(), month.into(), day.into())
1406 .ok_or_else(|| self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect))
1407 },
1408 _ => Err(self.reject(self.current_tag, ParseRejectReason::IncorrectDataFormatForValue)),
1409 }
1410 }
1411
1412 pub fn deserialize_local_mkt_time(&mut self) -> Result<LocalMktTime, DeserializeError> {
1423 match self.buf {
1424 [] => {
1425 Err(DeserializeError::GarbledMessage(format!(
1426 "no more data to parse tag {:?}",
1427 self.current_tag
1428 )))
1429 }
1430 [b'\x01', ..] => {
1431 Err(self.reject(self.current_tag, ParseRejectReason::TagSpecifiedWithoutAValue))
1432 }
1433 [_] => Err(DeserializeError::GarbledMessage(format!(
1435 "missing tag ({:?}) separator",
1436 self.current_tag
1437 ))),
1438
1439 [
1440 h1 @ b'0'..=b'2', h0 @ b'0'..=b'9',
1442 b':',
1443 m1 @ b'0'..=b'5', m0 @ b'0'..=b'0',
1445 b':',
1446 s1 @ b'0'..=b'5', s0 @ b'0'..=b'9',
1448 b'\x01',
1449 ..
1450 ] =>
1451 {
1452 let hour = (h1 - b'0') as u32 * 10 + (h0 - b'0') as u32;
1453 let minute = (m1 - b'0') as u32 * 10 + (m0 - b'0') as u32;
1454 let second = (s1 - b'0') as u32 * 10 + (s0 - b'0') as u32;
1455 self.buf = &self.buf[8..];
1456 LocalMktTime::from_hms_opt(hour, minute, second)
1457 .ok_or_else(|| self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect))
1458 }
1459 _ => Err(self.reject(self.current_tag, ParseRejectReason::IncorrectDataFormatForValue)),
1460 }
1461 }
1462
1463 pub fn deserialize_local_mkt_date(&mut self) -> Result<LocalMktDate, DeserializeError> {
1471 match self.buf {
1472 [] => {
1473 Err(DeserializeError::GarbledMessage(format!(
1474 "no more data to parse tag {:?}",
1475 self.current_tag
1476 )))
1477 }
1478 [b'\x01', ..] => Err(self.reject(self.current_tag, ParseRejectReason::TagSpecifiedWithoutAValue)),
1479 [_] => Err(DeserializeError::GarbledMessage(format!(
1481 "missing tag ({:?}) separator",
1482 self.current_tag
1483 ))),
1484 [
1485 y3 @ b'0'..=b'9', y2 @ b'0'..=b'9', y1 @ b'0'..=b'9', y0 @ b'0'..=b'9',
1487 m1 @ b'0'..=b'1', m0 @ b'0'..=b'9',
1489 d1 @ b'0'..=b'3', d0 @ b'0'..=b'9',
1491 b'\x01', ..
1493 ] => {
1494 let year = (y3 - b'0') as u16 * 1000
1495 + (y2 - b'0') as u16 * 100
1496 + (y1 - b'0') as u16 * 10
1497 + (y0 - b'0') as u16;
1498 let month = (m1 - b'0') * 10 + (m0 - b'0');
1499 let day = (d1 - b'0') * 10 + (d0 - b'0');
1500 self.buf = &self.buf[9..];
1501 LocalMktDate::from_ymd_opt(year.into(), month.into(), day.into())
1502 .ok_or_else(|| self.reject(self.current_tag, ParseRejectReason::ValueIsIncorrect))
1503 }
1504 _ => Err(self.reject(self.current_tag, ParseRejectReason::IncorrectDataFormatForValue)),
1505 }
1506 }
1507
1508 pub fn deserialize_tz_timestamp(&mut self) -> Result<TzTimestamp, DeserializeError> {
1528 match self.buf {
1529 [] => {
1530 return Err(DeserializeError::GarbledMessage(format!(
1531 "no more data to parse tag {:?}",
1532 self.current_tag
1533 )))
1534 }
1535 [b'\x01', ..] => {
1536 return Err(self.reject(
1537 self.current_tag,
1538 ParseRejectReason::TagSpecifiedWithoutAValue,
1539 ))
1540 }
1541 [_] => {
1543 return Err(DeserializeError::GarbledMessage(format!(
1544 "missing tag ({:?}) separator",
1545 self.current_tag
1546 )))
1547 }
1548 _ => {}
1549 }
1550 for i in 0..self.buf.len() {
1551 if let b'\x01' = unsafe { self.buf.get_unchecked(i) } {
1553 let data = &self.buf[0..i - 1];
1555 self.buf = &self.buf[i + 1..];
1556 return Ok(data.into());
1558 }
1559 }
1560
1561 Err(DeserializeError::GarbledMessage(format!(
1562 "no more data to parse tag {:?}",
1563 self.current_tag
1564 )))
1565 }
1566
1567 pub fn deserialize_tz_timeonly(&mut self) -> Result<TzTimeOnly, DeserializeError> {
1578 match self.buf {
1579 [] => {
1580 return Err(DeserializeError::GarbledMessage(format!(
1581 "no more data to parse tag {:?}",
1582 self.current_tag
1583 )))
1584 }
1585 &[b'\x01', ..] => {
1586 return Err(self.reject(
1587 self.current_tag,
1588 ParseRejectReason::TagSpecifiedWithoutAValue,
1589 ))
1590 }
1591 &[_] => {
1593 return Err(DeserializeError::GarbledMessage(format!(
1594 "missing tag ({:?}) separator",
1595 self.current_tag
1596 )))
1597 }
1598 _ => {}
1599 }
1600 for i in 0..self.buf.len() {
1601 if let b'\x01' = unsafe { self.buf.get_unchecked(i) } {
1603 let data = &self.buf[0..i - 1];
1605 self.buf = &self.buf[i + 1..];
1606 return Ok(data.into());
1607 }
1608 }
1609
1610 Err(DeserializeError::GarbledMessage(format!(
1611 "no more data to parse tag {:?}",
1612 self.current_tag
1613 )))
1614 }
1615
1616 pub fn deserialize_length(&mut self) -> Result<Length, DeserializeError> {
1626 match deserialize_length(self.buf) {
1627 Ok((leftover, len)) => {
1628 self.buf = leftover;
1629 Ok(len)
1630 }
1631 Err(DeserializeErrorInternal::Incomplete) => Err(DeserializeError::GarbledMessage(
1632 format!("no more data to parse tag {:?}", self.current_tag),
1633 )),
1634 Err(DeserializeErrorInternal::Error(reject)) => {
1635 Err(self.reject(self.current_tag, reject))
1636 }
1637 }
1638 }
1639
1640 pub fn deserialize_data(&mut self, len: usize) -> Result<Data, DeserializeError> {
1646 if self.buf.is_empty() {
1647 return Err(DeserializeError::GarbledMessage(format!(
1648 "no more data to parse tag {:?}",
1649 self.current_tag
1650 )));
1651 }
1652
1653 if self.buf.len() < len + 1 {
1655 return Err(DeserializeError::GarbledMessage(format!(
1656 "no more data to parse tag {:?}",
1657 self.current_tag
1658 )));
1659 }
1660
1661 if let b'\x01' = unsafe { *self.buf.get_unchecked(len + 1) } {
1663 return Err(DeserializeError::GarbledMessage(format!(
1665 "missing tag ({:?}) separator",
1666 self.current_tag
1667 )));
1668 }
1669
1670 let data = &self.buf[0..len];
1671 self.buf = &self.buf[len + 1..];
1673 Ok(data.into())
1674 }
1675
1676 pub fn deserialize_xml(&mut self, len: usize) -> Result<XmlData, DeserializeError> {
1687 match self.buf {
1688 [] => {
1689 return Err(DeserializeError::GarbledMessage(format!(
1690 "no more data to parse tag {:?}",
1691 self.current_tag
1692 )))
1693 }
1694 [b'\x01', ..] => {
1695 return Err(self.reject(
1696 self.current_tag,
1697 ParseRejectReason::TagSpecifiedWithoutAValue,
1698 ))
1699 }
1700 _ => {}
1701 }
1702
1703 if self.buf.len() < len + 1 {
1705 return Err(DeserializeError::GarbledMessage(format!(
1706 "no more data to parse tag {:?}",
1707 self.current_tag
1708 )));
1709 }
1710
1711 if let b'\x01' = unsafe { *self.buf.get_unchecked(len + 1) } {
1713 return Err(DeserializeError::GarbledMessage(format!(
1715 "missing tag ({:?}) separator",
1716 self.current_tag
1717 )));
1718 }
1719
1720 let xml = &self.buf[0..len];
1722 self.buf = &self.buf[len + 1..];
1724 Ok(xml.into())
1725 }
1726
1727 pub fn deserialize_int_enum<T>(&mut self) -> Result<T, DeserializeError>
1733 where
1734 T: TryFrom<Int, Error = ParseRejectReason>,
1735 {
1736 T::try_from(self.deserialize_int()?).map_err(|reason| self.reject(self.current_tag, reason))
1737 }
1738
1739 pub fn deserialize_num_in_group_enum<T>(&mut self) -> Result<T, DeserializeError>
1740 where
1741 T: TryFrom<NumInGroup, Error = ParseRejectReason>,
1742 {
1743 T::try_from(self.deserialize_num_in_group()?)
1744 .map_err(|reason| self.reject(self.current_tag, reason))
1745 }
1746
1747 pub fn deserialize_char_enum<T>(&mut self) -> Result<T, DeserializeError>
1748 where
1749 T: TryFrom<Char, Error = ParseRejectReason>,
1750 {
1751 let value = self.deserialize_char()?;
1752 T::try_from(value).map_err(|reason| self.reject(self.current_tag, reason))
1753 }
1754
1755 pub fn deserialize_string_enum<T>(&mut self) -> Result<T, DeserializeError>
1756 where
1757 for<'a> T: TryFrom<&'a FixStr, Error = ParseRejectReason>,
1758 {
1759 let value = self.deserialize_str()?;
1760 T::try_from(value).map_err(|reason| self.reject(self.current_tag, reason))
1761 }
1762
1763 pub fn deserialize_multiple_char_value_enum<T>(&mut self) -> Result<Vec<T>, DeserializeError>
1764 where
1765 T: TryFrom<Char, Error = ParseRejectReason>,
1766 {
1767 let values = self.deserialize_multiple_char_value()?;
1768 let mut result = Vec::with_capacity(values.len());
1769 for value in values {
1770 result
1771 .push(T::try_from(value).map_err(|reason| self.reject(self.current_tag, reason))?);
1772 }
1773 Ok(result)
1774 }
1775
1776 pub fn deserialize_multiple_string_value_enum<T>(&mut self) -> Result<Vec<T>, DeserializeError>
1777 where
1778 for<'a> T: TryFrom<&'a FixStr, Error = ParseRejectReason>,
1779 {
1780 let values = self.deserialize_multiple_string_value()?;
1781 let mut result = Vec::with_capacity(values.len());
1782 for value in values {
1783 result
1784 .push(T::try_from(&value).map_err(|reason| self.reject(self.current_tag, reason))?);
1785 }
1786 Ok(result)
1787 }
1788}
1789
1790#[cfg(test)]
1791mod tests {
1792 use std::str::FromStr;
1793
1794 use assert_matches::assert_matches;
1795 use chrono::{DateTime, NaiveDate, NaiveTime, TimeZone, Utc};
1796
1797 use super::{deserialize_tag, raw_message, Deserializer, RawMessage};
1798 use crate::{
1799 deserializer::{deserialize_checksum, RawMessageError},
1800 fields::{LocalMktDate, Price, TimePrecision},
1801 messages::BEGIN_STRING,
1802 };
1803
1804 #[test]
1805 fn deserialize_tag_ok() {
1806 assert_matches!(deserialize_tag(b"8=FIXT1.1\x01", b"8="), Ok(b"FIXT1.1\x01"));
1807 }
1808
1809 #[test]
1810 fn deserialize_tag_incomplete() {
1811 assert_matches!(
1812 deserialize_tag(b"", b"8="),
1813 Err(RawMessageError::Incomplete)
1814 );
1815
1816 assert_matches!(
1817 deserialize_tag(b"8", b"8="),
1818 Err(RawMessageError::Incomplete)
1819 );
1820 }
1821
1822 #[test]
1823 fn deserialize_tag_garbled() {
1824 assert_matches!(
1825 deserialize_tag(b"89FIXT1.1\x01", b"8="),
1826 Err(RawMessageError::Garbled)
1827 );
1828 }
1829
1830 #[test]
1831 fn deserialize_checksum_ok() {
1832 assert_matches!(deserialize_checksum(b"123\x01"), Ok((b"", 123)));
1833
1834 assert_matches!(
1835 deserialize_checksum(b"123\x01more data"),
1836 Ok((b"more data", 123))
1837 );
1838 }
1839
1840 #[test]
1841 fn deserialize_checksum_incomplete() {
1842 assert_matches!(deserialize_checksum(b"1"), Err(RawMessageError::Incomplete));
1843
1844 assert_matches!(
1845 deserialize_checksum(b"12"),
1846 Err(RawMessageError::Incomplete)
1847 );
1848
1849 assert_matches!(
1850 deserialize_checksum(b"123"),
1851 Err(RawMessageError::Incomplete)
1852 );
1853 }
1854
1855 #[test]
1856 fn deserialize_checksum_garbled() {
1857 assert_matches!(
1858 deserialize_checksum(b"A23\x01"),
1859 Err(RawMessageError::InvalidChecksum)
1860 );
1861
1862 assert_matches!(
1863 deserialize_checksum(b"1234"),
1864 Err(RawMessageError::InvalidChecksum)
1865 );
1866 assert_matches!(
1867 deserialize_checksum(b"1234\x01"),
1868 Err(RawMessageError::InvalidChecksum)
1869 );
1870 }
1871
1872 #[test]
1873 fn raw_message_ok() {
1874 let input = b"8=MSG_BODY\x019=19\x01<lots of tags here>10=143\x01";
1875 assert!(raw_message(input).is_ok());
1876 }
1877
1878 #[test]
1879 fn raw_message_from_chunks_ok() {
1880 let input = &[
1881 b"8=MSG_BOD".as_slice(),
1882 b"Y\x019=19\x01<lots".as_slice(),
1883 b" of tags here>10=143\x01".as_slice(),
1884 b"leftover".as_slice(),
1885 ];
1886 let mut buf = Vec::new();
1887 let mut i = input.iter();
1888 {
1889 buf.extend_from_slice(i.next().unwrap());
1890 assert!(matches!(
1891 raw_message(&buf),
1892 Err(RawMessageError::Incomplete)
1893 ));
1894 }
1895 {
1896 buf.extend_from_slice(i.next().unwrap());
1897 assert!(matches!(
1898 raw_message(&buf),
1899 Err(RawMessageError::Incomplete)
1900 ));
1901 }
1902 {
1903 buf.extend_from_slice(i.next().unwrap());
1904 assert!(matches!(raw_message(&buf), Ok(([], _))));
1905 }
1906 {
1907 buf.extend_from_slice(i.next().unwrap());
1908 assert!(matches!(raw_message(&buf), Ok((b"leftover", _))));
1909 }
1910 }
1911
1912 fn deserializer(body: &[u8]) -> Deserializer {
1913 let raw_message = RawMessage {
1914 begin_string: BEGIN_STRING,
1915 body,
1916 checksum: 0,
1917 };
1918
1919 Deserializer {
1920 raw_message,
1921 buf: body,
1922 msg_type: None,
1923 seq_num: Some(1),
1924 current_tag: None,
1925 tmp_tag: None,
1926 }
1927 }
1928
1929 #[test]
1930 fn deserialize_str_ok() {
1931 let input = b"lorem ipsum\x01\x00";
1932 let mut deserializer = deserializer(input);
1933 let buf = deserializer
1934 .deserialize_str()
1935 .expect("failed to deserialize utc timestamp");
1936 assert_eq!(buf, "lorem ipsum");
1937 assert_eq!(deserializer.buf, &[b'\x00']);
1938 }
1939
1940 #[test]
1941 fn deserialize_string_ok() {
1942 let input = b"lorem ipsum\x01\x00";
1943 let mut deserializer = deserializer(input);
1944 let buf = deserializer
1945 .deserialize_string()
1946 .expect("failed to deserialize utc timestamp");
1947 assert_eq!(buf, "lorem ipsum");
1948 assert_eq!(deserializer.buf, &[b'\x00']);
1949 }
1950
1951 #[test]
1952 fn deserialize_utc_timestamp_ok() {
1953 let input = b"20190605-11:51:27\x01\x00";
1954 let mut deserializer = deserializer(input);
1955 let utc_timestamp = deserializer
1956 .deserialize_utc_timestamp()
1957 .expect("failed to deserialize utc timestamp");
1958 let date_time: DateTime<Utc> = Utc.from_utc_datetime(
1959 &NaiveDate::from_ymd_opt(2019, 6, 5)
1960 .unwrap()
1961 .and_hms_opt(11, 51, 27)
1962 .unwrap(),
1963 );
1964 assert_eq!(utc_timestamp.timestamp(), date_time);
1965 assert_eq!(utc_timestamp.precision(), TimePrecision::Secs);
1966 assert_eq!(deserializer.buf, &[b'\x00']);
1967 }
1968
1969 #[test]
1970 fn deserialize_utc_timestamp_with_millis_ok() {
1971 let input = b"20190605-11:51:27.848\x01\x00";
1972 let mut deserializer = deserializer(input);
1973 let utc_timestamp = deserializer
1974 .deserialize_utc_timestamp()
1975 .expect("failed to deserialize utc timestamp");
1976 let date_time = Utc.from_utc_datetime(
1977 &NaiveDate::from_ymd_opt(2019, 6, 5)
1978 .unwrap()
1979 .and_hms_milli_opt(11, 51, 27, 848)
1980 .unwrap(),
1981 );
1982 assert_eq!(utc_timestamp.timestamp(), date_time);
1983 assert_eq!(utc_timestamp.precision(), TimePrecision::Millis);
1984 assert_eq!(deserializer.buf, &[b'\x00']);
1985 }
1986
1987 #[test]
1988 fn deserialize_utc_timestamp_with_micros_ok() {
1989 let input = b"20190605-11:51:27.848757\x01\x00";
1990 let mut deserializer = deserializer(input);
1991 let utc_timestamp = deserializer
1992 .deserialize_utc_timestamp()
1993 .expect("failed to deserialize utc timestamp");
1994 let date_time = Utc.from_utc_datetime(
1995 &NaiveDate::from_ymd_opt(2019, 6, 5)
1996 .unwrap()
1997 .and_hms_micro_opt(11, 51, 27, 848757)
1998 .unwrap(),
1999 );
2000 assert_eq!(utc_timestamp.timestamp(), date_time);
2001 assert_eq!(utc_timestamp.precision(), TimePrecision::Micros);
2002 assert_eq!(deserializer.buf, &[b'\x00']);
2003 }
2004
2005 #[test]
2006 fn deserialize_utc_timestamp_with_nanos_ok() {
2007 let input = b"20190605-11:51:27.848757123\x01\x00";
2008 let mut deserializer = deserializer(input);
2009 let utc_timestamp = deserializer
2010 .deserialize_utc_timestamp()
2011 .expect("failed to deserialize utc timestamp");
2012 let date_time = Utc.from_utc_datetime(
2013 &NaiveDate::from_ymd_opt(2019, 6, 5)
2014 .unwrap()
2015 .and_hms_nano_opt(11, 51, 27, 848757123)
2016 .unwrap(),
2017 );
2018 assert_eq!(utc_timestamp.timestamp(), date_time);
2019 assert_eq!(utc_timestamp.precision(), TimePrecision::Nanos);
2020 assert_eq!(deserializer.buf, &[b'\x00']);
2021 }
2022
2023 #[test]
2024 fn deserialize_utc_timestamp_with_picos_ok() {
2025 let input = b"20190605-11:51:27.848757123999\x01\x00";
2026 let mut deserializer = deserializer(input);
2027 let utc_timestamp = deserializer
2028 .deserialize_utc_timestamp()
2029 .expect("failed to deserialize utc timestamp");
2030 let date_time = Utc.from_utc_datetime(
2031 &NaiveDate::from_ymd_opt(2019, 6, 5)
2032 .unwrap()
2033 .and_hms_nano_opt(11, 51, 27, 848757123)
2034 .unwrap(),
2035 );
2036 assert_eq!(utc_timestamp.timestamp(), date_time);
2037 assert_eq!(utc_timestamp.precision(), TimePrecision::Nanos);
2038 assert_eq!(deserializer.buf, &[b'\x00']);
2039 }
2040
2041 #[ignore]
2043 #[test]
2044 fn deserialize_utc_timeonly_ok() {
2045 let input = b"11:51:27\x01\x00";
2046 let mut deserializer = deserializer(input);
2047 let utc_timeonly = deserializer
2048 .deserialize_utc_time_only()
2049 .expect("failed to deserialize utc timeonly");
2050 let time: NaiveTime = NaiveTime::from_hms_opt(11, 51, 27).unwrap();
2051 assert_eq!(utc_timeonly.timestamp(), time);
2052 assert_eq!(utc_timeonly.precision(), TimePrecision::Secs);
2053 assert_eq!(deserializer.buf, &[b'\x00']);
2054 }
2055
2056 #[test]
2057 fn deserialize_local_mkt_date_ok() {
2058 let input = b"20220530\x01\x00";
2059 let mut deserializer = deserializer(input);
2060 let local_mkt_date = deserializer
2061 .deserialize_local_mkt_date()
2062 .expect("failed to deserialize utc timestamp");
2063 assert_eq!(
2064 local_mkt_date,
2065 LocalMktDate::from_ymd_opt(2022, 5, 30).unwrap()
2066 );
2067 assert_eq!(deserializer.buf, &[b'\x00']);
2068 }
2069
2070 #[test]
2071 fn deserialize_price_ok() {
2072 let values: &[(&[u8], Price)] = &[
2073 (b"97\x01\x00", Price::from_str("97").expect("Wrong decimal")),
2074 (
2075 b"97.\x01\x00",
2076 Price::from_str("97.").expect("Wrong decimal"),
2077 ),
2078 (
2079 b"97.0347\x01\x00",
2080 Price::from_str("97.0347").expect("Wrong decimal"),
2081 ),
2082 ];
2083 for (input, value) in values {
2084 let mut deserializer = deserializer(input);
2085 let price = deserializer
2086 .deserialize_price()
2087 .expect("failed to deserialize price");
2088 assert_eq!(price, *value);
2089 assert_eq!(deserializer.buf, &[b'\x00']);
2090 }
2091 }
2092}