Skip to main content

hotfix_message/
field_map.rs

1use crate::FieldType;
2use crate::Part;
3use crate::parts::RepeatingGroup;
4use hotfix_dictionary::TagU32;
5use indexmap::IndexMap;
6
7#[derive(Clone, Debug)]
8pub struct Field {
9    pub(crate) tag: TagU32,
10    pub data: Vec<u8>,
11}
12
13impl Field {
14    pub fn new(tag: TagU32, data: Vec<u8>) -> Self {
15        Self { tag, data }
16    }
17
18    pub fn calculate_length(&self) -> usize {
19        self.tag.to_bytes().len() + self.data.len() + 2
20    }
21}
22
23#[derive(Clone, Debug, Default)]
24pub struct FieldMap {
25    pub fields: IndexMap<TagU32, Field>,
26    pub groups: IndexMap<TagU32, Vec<RepeatingGroup>>,
27}
28
29impl FieldMap {
30    pub fn insert(&mut self, field: Field) {
31        self.fields.insert(field.tag, field);
32    }
33
34    pub fn set_groups(&mut self, start_tag: TagU32, groups: Vec<RepeatingGroup>) {
35        self.groups.insert(start_tag, groups);
36    }
37
38    pub fn get_raw(&self, tag: TagU32) -> Option<&[u8]> {
39        self.fields.get(&tag).map(|f| f.data.as_slice())
40    }
41
42    pub fn get_group(&self, start_tag: TagU32, index: usize) -> Option<&RepeatingGroup> {
43        self.groups
44            .get(&start_tag)
45            .and_then(|groups| groups.get(index))
46    }
47
48    pub fn calculate_length(&self, skip: &[TagU32]) -> usize {
49        let fields_length: usize = self
50            .fields
51            .values()
52            .filter(|f| !skip.contains(&f.tag))
53            .map(|f| f.calculate_length())
54            .sum();
55        let groups_length: usize = self
56            .groups
57            .iter()
58            .flat_map(|g| g.1)
59            .map(|g| g.calculate_length())
60            .sum();
61
62        fields_length + groups_length
63    }
64}