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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//! A wide collection of [`FieldType`](crate::FieldType) implementors.
//!
//! | FIX datatype | Suggested [`FieldType`] implementors |
//! |----------------------------|------------------------------------------------------------------------------------|
//! | `int` | [`u32`], [`i32`], [`u64`], [`i64`], [`u128`], [`i128`]. |
//! | `Length` | [`usize`]. |
//! | `NumInGroup` | [`usize`]. |
//! | `SeqNum` | [`u64`]. |
//! | `TagNum` | [`TagU32`](crate::TagU32). |
//! | `DayOfMonth` | [`u32`]. |
//! | `float`, `Price`, etc. | [`f32`], [`f64`], [`struct@rust_decimal::Decimal`], [`struct@decimal::d128`]. |
//! | `Boolean` | [`bool`]. |
//! | `char` | [`u8`] [^1]. |
//! | `String` | [`Vec<u8>`], `&[u8]`.[^1] |
//! | `data` | [`Vec<u8>`], `&[u8]` (also [`String`], [`str`] for UTF-8 content). |
//! | `MultipleCharValue` | [`MultipleChars`] [^1]. |
//! | `MultipleValueString` | [`MultipleStrings`] [^1]. |
//! | `Country` | [`Country`]. |
//! | `Currency` | [`Currency`]. |
//! | `Exchange` | [`Exchange`]. |
//! | `month-year` | [`MonthYear`]. |
//! | `UTCTimeOnly` | [`Time`], [`chrono::NaiveTime`]. |
//! | `UTCDateOnly` | [`Date`], [`chrono::NaiveDate`]. |
//! | `UTCTimestamp` | [`Timestamp`], [`chrono::NaiveDateTime`]. |
//! | `TZTimestamp` | [`TzTimestamp`], [`chrono::DateTime<chrono::FixedOffset>`]. |
//! | `LocalMktDate` | [`Date`], [`chrono::NaiveDate`]. |
//! | `TZTimeOnly` | [`TzTime`], |
//!
//! The above table provides some useful guidelines that work for the vast
//! majority of use cases.
//!
//! # Quick tour of [`FieldType`]
//!
//! ```
//! use hotfix_encoding::field_access::FieldType;
//! use hotfix_encoding::field_types::Timestamp;
//!
//! let bytes = b"20130422-12:30:00.000";
//!
//! // You can use `FieldType::deserialize` to parse data fields.
//! let timestamp = Timestamp::deserialize(bytes).unwrap();
//! assert_eq!(timestamp.date().year(), 2013);
//!
//! // `FieldType::deserialize_lossy` is like `FieldType::deserialize`, but it's
//! // allowed to skip some format verification for the sake of speed.
//! assert!(u32::deserialize(b"invalid integer").is_err());
//! assert!(u32::deserialize_lossy(b"invalid integer").is_ok());
//!
//! let mut buffer: Vec<u8> = vec![];
//! // Use `FieldType::serialize` to write values to buffers.
//! 1337u32.serialize(&mut buffer);
//! assert_eq!(&buffer[..], b"1337" as &[u8]);
//! ```
//!
//! [^1]: With the exception of datatype `data`, FIX mandates a single-byte
//! encoding (Latin alphabet No. 1 by default), while Rust strings are UTF-8,
//! which is a multibyte encoding. These are *not* compatible. Watch out!
pub use CheckSum;
pub use Date;
pub use MonthYear;
pub use MultipleChars;
pub use MultipleStrings;
pub use Time;
pub use Timestamp;
pub use Tz;
pub use TzTime;
pub use TzTimestamp;
use crateFieldType;
/// Type alias for ISO 3166-1 alpha-2 strings (two-letter country codes).
pub type Country = ;
/// Type alias for ISO 4217 alpha codes (three-letter currency codes).
pub type Currency = ;
/// Type alias for four-letter *Market Identifier Codes* (MICs) as defined by
/// ISO 10383.
pub type Exchange = ;
pub const ERR_UTF8: &str = "Invalid byte sequence; expected UTF-8 valid bytes.";
pub const ERR_INT_INVALID: &str = "Invalid integer digits.";
pub const ERR_TIME: &str = "Invalid time.";
/// Zero-padding for integers; see [`FieldType::SerializeSettings`].
;
/// Tries to [`FieldType::serialize`] an `item`, then to
/// [`FieldType::deserialize`] it, and finally checks for equality with the
/// initial data. [`FieldType::deserialize_lossy`] is then
/// tested in the same manner.