1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use field_tag::FieldTag;
use field_type::FieldType;
use fix_version::FIXVersion;
use message_version::MessageVersion;
use rule::Rule;
pub trait Field {
type Type;
fn rule() -> Rule;
fn tag_bytes() -> &'static [u8];
fn tag() -> FieldTag;
fn read(field: &<<Self as Field>::Type as FieldType>::Type,fix_version: FIXVersion,message_version: MessageVersion,buf: &mut Vec<u8>,required: bool) -> usize
where <Self as Field>::Type: FieldType;
}
#[macro_export]
macro_rules! define_fields {
( $( $field_name:ident : $field_type:ty = $tag:expr $( => $rule:expr )* ),* $(),* ) => { $(
#[derive(BuildField)]
pub struct $field_name {
#[tag=$tag]
_tag_gen: ::std::marker::PhantomData<()>,
}
impl $crate::field::Field for $field_name {
type Type = $field_type;
#[allow(unreachable_code)]
fn rule() -> $crate::rule::Rule {
$(
return $rule
)*;
if let Some(rule) = <$field_type as $crate::field_type::FieldType>::rule() {
rule
}
else {
$crate::rule::Rule::Nothing
}
}
fn tag_bytes() -> &'static [u8] {
Self::tag_bytes()
}
fn tag() -> $crate::field_tag::FieldTag {
Self::tag()
}
fn read(field: &<<Self as $crate::field::Field>::Type as $crate::field_type::FieldType>::Type,fix_version: $crate::fix_version::FIXVersion,message_version: $crate::message_version::MessageVersion,buf: &mut Vec<u8>,required: bool) -> usize {
use ::std::io::Write;
if !required && <$field_type as $crate::field_type::FieldType>::is_empty(field) {
return 0;
}
let mut result = 1;
match <$field_name as $crate::field::Field>::rule() {
$crate::rule::Rule::PrepareForBytes{ .. } => {
return 0;
},
$crate::rule::Rule::ConfirmPreviousTag{ previous_tag } => {
let previous_tag = previous_tag.to_bytes();
result += 2;
result += buf.write(&previous_tag[..]).unwrap();
buf.push($crate::constant::TAG_END);
result += buf.write(<$field_type as $crate::field_type::FieldType>::len(field).to_string().as_bytes()).unwrap();
buf.push($crate::constant::VALUE_END);
},
$crate::rule::Rule::RequiresFIXVersion{ fix_version: required_fix_version } => {
if fix_version != required_fix_version {
return 0;
}
},
_ => {},
};
result += buf.write(Self::tag_bytes()).unwrap();
buf.push($crate::constant::TAG_END);
result += <$field_type as $crate::field_type::FieldType>::read(field,fix_version,message_version,buf);
if let $crate::rule::Rule::BeginGroup{ .. } = <$field_name as $crate::field::Field>::rule() {}
else {
result += 1;
buf.push($crate::constant::VALUE_END);
}
result
}
}
)*};
}