1use chrono::DateTime;
2use chrono::Utc;
3
4use crate::FixChecksum;
5use crate::FixLength;
6use crate::fields::converters::IntoBytes;
7use crate::fields::converters::TryFrom;
8use crate::fields::ConversionError;
9use crate::message::Message;
10use crate::tags;
11use std::collections::BTreeMap;
12use std::collections::BTreeSet;
13use std::collections::HashMap;
14use std::num::Wrapping;
15use std::ops::{Deref, DerefMut};
16
17#[derive(Default, Clone, Debug)]
18pub struct FieldMap {
19 fields: BTreeMap<Tag, Field>,
21 groups: HashMap<Tag, Vec<Group>>,
22 repeated_tags: Vec<Field>,
25 _field_order: FieldOrder,
26}
27
28pub type Tag = i32;
29pub type Total = u32;
30pub type Length = u32;
31pub type FieldOrder = Vec<Tag>;
32pub(crate) type FieldBase = Field;
33pub type FieldValue = std::sync::Arc<[u8]>;
35
36#[derive(Clone, Debug)]
37pub enum FieldMapError {
38 FieldNotFound(Tag),
39 ConversionError(ConversionError),
40}
41
42impl From<ConversionError> for FieldMapError {
43 fn from(err: ConversionError) -> Self {
44 FieldMapError::ConversionError(err)
45 }
46}
47
48#[derive(Default, Clone, Debug)]
49pub struct Group {
50 delim: Tag,
51 field: Tag,
52 map: FieldMap,
53 field_order: Option<FieldOrder>,
54}
55impl Group {
56 pub fn new(field: Tag, delim: Tag) -> Self {
57 Group {
58 delim,
59 field,
60 map: FieldMap::default(),
61 field_order: None,
62 }
63 }
64 pub fn delim(&self) -> Tag {
65 self.delim
66 }
67 pub fn field(&self) -> Tag {
68 self.field
69 }
70 pub fn calculate_string(&self) -> String {
71 if let Some(order) = &self.field_order {
72 todo!("calculate order: {:?}", order)
73 } else {
74 let order: Vec<Tag> = vec![self.delim];
75 self.map.calculate_string(Some(order))
76 }
77 }
78}
79impl Deref for Group {
80 type Target = FieldMap;
81 fn deref(&self) -> &Self::Target {
82 &self.map
83 }
84}
85
86impl DerefMut for Group {
87 fn deref_mut(&mut self) -> &mut Self::Target {
88 &mut self.map
89 }
90}
91#[derive(Clone, Debug, PartialEq, Eq)]
92pub struct Field(Tag, FieldValue);
93impl Default for Field {
94 fn default() -> Self {
95 Self(Default::default(), vec![].into())
96 }
97}
98
99impl Field {
100 pub fn new<'a, T: IntoBytes<FieldValue> + TryFrom<&'a FieldValue, Error = ConversionError>>(tag: Tag, value: T) -> Self {
101 Field(tag, value.as_bytes())
102 }
103 pub fn from_bytes(tag: Tag, value: std::sync::Arc<[u8]>) -> Self {
104 Field(tag, value)
105 }
106 pub fn tag(&self) -> Tag {
107 self.0
108 }
109 pub fn value(&self) -> &FieldValue {
110 &self.1
111 }
112 pub(crate) fn string_value(&self) -> Result<String, ConversionError> {
113 self.as_value()
114 }
115 pub(crate) fn to_string_field(&self) -> String {
116 format!("{}={}", self.tag(), self.as_value::<&str>().ok().unwrap_or(""))
117 }
118 pub fn as_value<'a, T>(&'a self) -> Result<T, ConversionError>
119 where
120 T: TryFrom<&'a FieldValue, Error = ConversionError>,
121 {
122 TryFrom::try_from(&self.1)
123 }
124
125 pub(crate) fn to_usize(&self) -> Option<usize> {
126 self.string_value().ok().map(|v| match v.parse::<usize>() {
127 Ok(value) => Some(value),
128 Err(_) => None,
129 }).flatten()
130 }
131}
132
133impl FixChecksum for &Field {
134 fn checksum(self) -> std::num::Wrapping<u8> {
135 self.tag().checksum() +
136 Wrapping(b'=' as u8) +
137 self.value().checksum() +
138 Wrapping(1) }
140}
141
142impl FixLength for &Field {
143 fn bytes_len(self) -> u32 {
144 self.tag().bytes_len() +
145 1 + self.value().bytes_len() +
147 1 }
149}
150
151impl FieldMap {
152 pub fn from_field_order(_field_order: FieldOrder) -> Self {
153 let fields = Default::default();
154 let groups = Default::default();
155 let repeated_tags = Vec::default();
156 FieldMap {
157 fields,
158 groups,
159 repeated_tags,
160 _field_order,
161 }
162 }
163
164 pub fn from_field_map(src: &FieldMap) -> Self {
165 src.clone()
166 }
167
168 pub fn set_field_base(&mut self, field: Field, overwrite: Option<bool>) -> bool {
169 if matches!(overwrite, Some(b) if !b) && self.fields.contains_key(&field.tag()) {
170 return false;
171 }
172 self.fields.insert(field.tag(), field);
173 true
174 }
175
176 pub fn set_field_deref<F: Deref<Target = Field> + Clone>(
177 &mut self,
178 field: F,
179 overwrite: Option<bool>,
180 ) -> bool {
181 if matches!(overwrite, Some(b) if b) {
182 return false;
183 }
184 let field: &Field = &field;
185 self.fields.insert(field.tag(), field.clone());
186 true
187 }
188
189 pub fn set_tag_value<'a, T: IntoBytes<FieldValue>>(&mut self, tag: Tag, value: T) {
190 let field_base = Field(tag, value.as_bytes());
191 self.set_field_base(field_base, None);
192 }
193
194 pub fn set_field<'a, T: Into<Field>>(&mut self, field: T) {
195 self.set_field_base(field.into(), None);
196 }
197
198 pub fn get_field(&self, tag: Tag) -> Option<&Field> {
199 self.fields.get(&tag)
200 }
201
202 pub fn get_int(&self, tag: Tag) -> Result<u32, FieldMapError> {
204 match self.fields.get(&tag) {
205 None => Err(FieldMapError::FieldNotFound(tag)),
206 Some(value) => Ok(value.as_value()?),
207 }
208 }
209 pub fn get_string(&self, tag: Tag) -> Result<String, FieldMapError> {
210 match self.fields.get(&tag) {
211 None => Err(FieldMapError::FieldNotFound(tag)),
212 Some(value) => Ok(value.string_value()?),
213 }
214 }
215 pub fn get_string_unchecked(&self, tag: Tag) -> String {
216 self.fields[&tag].string_value().unwrap().into() }
218 pub fn get_bool(&self, tag: Tag) -> bool {
219 self.fields[&tag].string_value().ok() == Some("Y".into())
220 }
221 pub fn get_datetime(&self, tag: Tag) -> Result<DateTime<Utc>, ConversionError> {
222 self.fields[&tag].as_value()
223 }
224 pub fn get_field_mut(&mut self, tag: Tag) -> Option<&mut Field> {
227 self.fields.get_mut(&tag)
228 }
229 pub fn is_field_set(&self, tag: Tag) -> bool {
230 self.fields.contains_key(&tag)
231 }
232 pub fn remove_field(&mut self, tag: Tag) {
233 self.fields.remove(&tag);
234 }
235
236 pub fn add_group(&mut self, _tag: Tag, group: &Group, set_count: Option<bool>) {
238 self.groups.entry(group.field()).or_insert_with(Vec::new);
239 self.groups
240 .get_mut(&group.field())
241 .unwrap() .push(group.clone());
243
244 if set_count.unwrap_or(true) {
245 let groupsize = self.groups[&group.field()].len();
248 let counttag = group.field();
249 let count = Field::new(counttag, format!("{}", groupsize));
251
252 self.set_field_base(count, Some(true));
253 }
254 }
255 pub fn get_group(&self, index: u32, field: Tag) -> Result<&Group, FieldMapError> {
258 if !self.groups.contains_key(&field) {
259 return Err(FieldMapError::FieldNotFound(field));
260 }
261 if index == 0 {
262 return Err(FieldMapError::FieldNotFound(field));
263 }
264 if self.groups[&field].len() < index as usize {
265 return Err(FieldMapError::FieldNotFound(field));
266 }
267
268 Ok(&self.groups[&field][(index-1) as usize])
269 }
270 pub fn get_group_mut(&mut self, index: u32, field: Tag) -> Result<&mut Group, FieldMapError> {
273 if !self.groups.contains_key(&field) {
274 return Err(FieldMapError::FieldNotFound(field));
275 }
276 if index == 0 {
277 return Err(FieldMapError::FieldNotFound(field));
278 }
279 if self.groups[&field].len() < index as usize {
280 return Err(FieldMapError::FieldNotFound(field));
281 }
282
283 Ok(&mut self.groups.get_mut(&field).ok_or_else(|| FieldMapError::FieldNotFound(field))?[index as usize - 1])
285 }
286 pub fn remove_group(&mut self, index: u32, field: Tag) -> Result<(), FieldMapError> {
289 if !self.groups.contains_key(&field) {
290 return Err(FieldMapError::FieldNotFound(field));
291 }
292 if index == 0 {
293 return Err(FieldMapError::FieldNotFound(field));
294 }
295 if self.groups[&field].len() < index as usize {
296 return Err(FieldMapError::FieldNotFound(field));
297 }
298
299 if self.groups[&field].len() == 1 {
300 self.groups.remove(&field);
301 } else {
302 self.groups
303 .get_mut(&field)
304 .ok_or_else(|| FieldMapError::FieldNotFound(field))?
305 .remove((index as usize) - 1);
307 }
308 Ok(())
309 }
310 pub fn replace_group(
311 &mut self,
312 index: Tag,
313 field: Tag,
314 group: Group,
315 ) -> Result<Group, FieldMapError> {
316 if !self.groups.contains_key(&field) {
317 return Err(FieldMapError::FieldNotFound(field));
318 }
319 if index == 0 {
320 return Err(FieldMapError::FieldNotFound(field));
321 }
322 if self.groups[&field].len() < index as usize {
323 return Err(FieldMapError::FieldNotFound(field));
324 }
325
326 let group_ref = self
327 .groups
328 .get_mut(&field)
329 .ok_or_else(|| FieldMapError::FieldNotFound(field))?
330 .get_mut(index as usize - 1)
332 .ok_or_else(|| FieldMapError::FieldNotFound(field))?;
333 let group = std::mem::replace(group_ref, group);
334
335 Ok(group)
336 }
337
338 pub fn group_tags(&self) -> impl Iterator<Item = &Tag> {
339 self.groups.keys()
340 }
341
342 pub fn group_count(&self, field: Tag) -> Result<usize, FieldMapError> {
343 if !self.groups.contains_key(&field) {
344 return Err(FieldMapError::FieldNotFound(field));
345 }
346 Ok(self.groups[&field].len())
347 }
348
349 pub fn is_empty(&self) -> bool {
350 self.fields.len() == 0 && self.groups.len() == 0
351 }
352
353 pub fn calculate_total(&self) -> Total {
354 let mut total = 0;
355 for field in self.fields.values() {
356 if field.tag() != tags::CheckSum {
357 total += field.checksum().0 as Total;
358 }
359 }
360
361 for field in self.repeated_tags() {
362 if field.tag() != tags::CheckSum {
363 total += field.checksum().0 as Total;
364 }
365 }
366
367 for group_list in self.groups.values() {
368 for group in group_list {
369 total += group.calculate_total();
370 }
371 }
372 total
373 }
374
375 pub fn len(&self) -> Length {
376 let mut total = 0;
377 for field in self.fields.values() {
378 if field.tag() != tags::CheckSum
379 && field.tag() != tags::BeginString
380 && field.tag() != tags::BodyLength
381 {
382 total += field.bytes_len();
383 }
384 }
385
386 for field in self.repeated_tags() {
387 if field.tag() != tags::CheckSum
388 && field.tag() != tags::BeginString
389 && field.tag() != tags::BodyLength
390 {
391 total += field.bytes_len();
392 }
393 }
394
395 for group_list in self.groups.values() {
396 for group in group_list {
397 total += group.len();
398 }
399 }
400
401 total
402 }
403
404 pub fn repeated_tags(&self) -> &Vec<Field> {
405 &self.repeated_tags
406 }
407
408 pub fn repeated_tags_mut(&mut self) -> &mut Vec<Field> {
409 &mut self.repeated_tags
410 }
411
412 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Tag, &Field)> {
413 self.fields.iter()
414 }
415
416 pub fn clear(&mut self) {
417 self.fields.clear();
418 self.groups.clear();
419 }
420
421 pub fn calculate_string(&self, prefields: Option<FieldOrder>) -> String {
422 let group_counter_tags: BTreeSet<&Tag> = self.group_tags().collect();
423 let prefields = prefields.unwrap_or_default();
424 let mut sb = String::new();
425
426 for prefield in &prefields {
427 if self.is_field_set(*prefield) {
428 sb.push_str(
429 format!(
430 "{}={}{}",
431 prefield,
432 self.get_string_unchecked(*prefield),
433 Message::SOH
434 )
435 .as_str(),
436 );
437 if group_counter_tags.contains(prefield) {
438 let glist = &self.groups[prefield];
439 for g in glist {
440 sb.push_str(&g.calculate_string());
441 }
442 }
443 }
444 }
445
446 for field in self.fields.values() {
447 if group_counter_tags.contains(&field.tag()) {
448 continue;
449 }
450 if prefields.contains(&field.tag()) {
451 continue; }
453 sb.push_str(
454 format!("{}={}{}", field.tag(), field.string_value().unwrap(), Message::SOH).as_str(),
455 );
456 }
457
458 for counter_tag in self.groups.keys() {
459 if prefields.contains(counter_tag) {
460 continue; }
462
463 let grouplist = &self.groups[counter_tag];
464 if grouplist.is_empty() {
465 continue; }
467
468 sb.push_str(
469 format!(
470 "{}{}",
471 self.fields[counter_tag].to_string_field(),
472 Message::SOH
473 )
474 .as_str(),
475 );
476
477 for group in grouplist {
478 sb.push_str(&group.calculate_string());
479 }
480 }
481
482 sb
483 }
484}
485
486#[cfg(test)]
487mod tests {
488 use super::FieldValue;
489 use super::Tag;
490 use std::any::Any;
491 use std::any::TypeId;
492
493 trait TagValue: Any {
494 fn tag(&self) -> Tag;
495 fn value(&self) -> &FieldValue;
496 fn as_any(&self) -> &dyn Any;
497 }
498
499 #[derive(Debug)]
500 struct Test {
501 pub tag: Tag,
502 pub value: FieldValue,
503 }
504 impl TagValue for Test {
505 fn tag(&self) -> Tag {
506 self.tag
507 }
508 fn value(&self) -> &FieldValue {
509 &self.value
510 }
511 fn as_any(&self) -> &dyn Any {
512 self
513 }
514 }
515 impl<T: TagValue> From<T> for Box<dyn TagValue> {
516 fn from(tag_value: T) -> Self {
517 Box::new(tag_value)
518 }
519 }
520
521 #[test]
522 fn box_test() {
523 let boxed = Test {
524 tag: 0,
525 value: "Hello".as_bytes().into(),
526 }
527 .into();
528 let boxed_vec: Vec<Box<dyn TagValue>> = vec![boxed];
529 for value in boxed_vec {
530 let value: &dyn TagValue = &*value;
531 if value.type_id() == TypeId::of::<Test>() {
532 let result = value.as_any().downcast_ref::<Test>();
533 assert!(result.is_some());
534 } else {
535 panic!()
536 }
537 }
538 }
539}