1use std::convert::TryFrom;
8
9const WXF_VERSION: u8 = b'8';
12const WXF_HEADER_SEPARATOR: u8 = b':';
13const WXF_HEADER_COMPRESS: u8 = b'C';
14
15const WXF_FUNCTION: u8 = b'f';
16const WXF_SYMBOL: u8 = b's';
17const WXF_STRING: u8 = b'S';
18const WXF_BYTE_ARRAY: u8 = b'B';
19const WXF_INTEGER8: u8 = b'C';
20const WXF_INTEGER16: u8 = b'j';
21const WXF_INTEGER32: u8 = b'i';
22const WXF_INTEGER64: u8 = b'L';
23const WXF_REAL64: u8 = b'r';
24const WXF_BIG_INTEGER: u8 = b'I';
25const WXF_BIG_REAL: u8 = b'R';
26const WXF_PACKED_ARRAY: u8 = 0xC1;
27const WXF_NUMERIC_ARRAY: u8 = 0xC2;
28const WXF_ASSOCIATION: u8 = b'A';
29const WXF_RULE: u8 = b'-';
30const WXF_RULE_DELAYED: u8 = b':';
31
32const WXF_ARRAY_INTEGER8: u8 = 0x00;
33const WXF_ARRAY_INTEGER16: u8 = 0x01;
34const WXF_ARRAY_INTEGER32: u8 = 0x02;
35const WXF_ARRAY_INTEGER64: u8 = 0x03;
36const WXF_ARRAY_UNSIGNED_INTEGER8: u8 = 0x10;
37const WXF_ARRAY_UNSIGNED_INTEGER16: u8 = 0x11;
38const WXF_ARRAY_UNSIGNED_INTEGER32: u8 = 0x12;
39const WXF_ARRAY_UNSIGNED_INTEGER64: u8 = 0x13;
40const WXF_ARRAY_REAL32: u8 = 0x22;
41const WXF_ARRAY_REAL64: u8 = 0x23;
42const WXF_ARRAY_COMPLEX_REAL32: u8 = 0x33;
43const WXF_ARRAY_COMPLEX_REAL64: u8 = 0x34;
44
45fn token_to_size_in_bytes(byte: u8) -> usize {
52 match byte {
53 WXF_ARRAY_INTEGER8 | WXF_ARRAY_UNSIGNED_INTEGER8 => 1,
54 WXF_ARRAY_INTEGER16 | WXF_ARRAY_UNSIGNED_INTEGER16 => 2,
55 WXF_ARRAY_INTEGER32 | WXF_ARRAY_UNSIGNED_INTEGER32 | WXF_ARRAY_REAL32 => 4,
56 WXF_ARRAY_INTEGER64
57 | WXF_ARRAY_UNSIGNED_INTEGER64
58 | WXF_ARRAY_REAL64
59 | WXF_ARRAY_COMPLEX_REAL32 => 8,
60 WXF_ARRAY_COMPLEX_REAL64 => 16,
61 _ => panic!("token_to_size_in_bytes: unknown byte 0x{:02X}", byte),
62 }
63}
64
65fn token_to_name(byte: u8) -> &'static str {
66 match byte {
67 WXF_FUNCTION => "Function",
68 WXF_SYMBOL => "Symbol",
69 WXF_STRING => "String",
70 WXF_BYTE_ARRAY => "ByteArray",
71 WXF_INTEGER8 => "Integer8",
72 WXF_INTEGER16 => "Integer16",
73 WXF_INTEGER32 => "Integer32",
74 WXF_INTEGER64 => "Integer64",
75 WXF_REAL64 => "Real64",
76 WXF_BIG_INTEGER => "BigInteger",
77 WXF_BIG_REAL => "BigReal",
78 WXF_PACKED_ARRAY => "PackedArray",
79 WXF_NUMERIC_ARRAY => "NumericArray",
80 WXF_ASSOCIATION => "Association",
81 WXF_RULE => "Rule",
82 WXF_RULE_DELAYED => "RuleDelayed",
83 WXF_ARRAY_INTEGER8 => "Integer8",
84 WXF_ARRAY_INTEGER16 => "Integer16",
85 WXF_ARRAY_INTEGER32 => "Integer32",
86 WXF_ARRAY_INTEGER64 => "Integer64",
87 WXF_ARRAY_UNSIGNED_INTEGER8 => "UnsignedInteger8",
88 WXF_ARRAY_UNSIGNED_INTEGER16 => "UnsignedInteger16",
89 WXF_ARRAY_UNSIGNED_INTEGER32 => "UnsignedInteger32",
90 WXF_ARRAY_UNSIGNED_INTEGER64 => "UnsignedInteger64",
91 WXF_ARRAY_REAL32 => "Real32",
92 WXF_ARRAY_REAL64 => "Real64",
93 WXF_ARRAY_COMPLEX_REAL32 => "ComplexReal32",
94 WXF_ARRAY_COMPLEX_REAL64 => "ComplexReal64",
95 _ => "<unknown>",
96 }
97}
98
99#[derive(Debug, Copy, Clone, PartialEq, Eq, num_enum::TryFromPrimitive)]
106#[repr(u8)]
107pub enum HeaderEnum {
108 Version = WXF_VERSION,
110 Separator = WXF_HEADER_SEPARATOR,
112 Compress = WXF_HEADER_COMPRESS,
115}
116
117#[derive(Debug, Copy, Clone, PartialEq, Eq, num_enum::TryFromPrimitive)]
123#[repr(u8)]
124pub enum ExpressionEnum {
125 Function = WXF_FUNCTION,
128 Symbol = WXF_SYMBOL,
130 String = WXF_STRING,
132 ByteArray = WXF_BYTE_ARRAY,
134 Integer8 = WXF_INTEGER8,
136 Integer16 = WXF_INTEGER16,
138 Integer32 = WXF_INTEGER32,
140 Integer64 = WXF_INTEGER64,
142 Real64 = WXF_REAL64,
144 BigInteger = WXF_BIG_INTEGER,
146 BigReal = WXF_BIG_REAL,
148 PackedArray = WXF_PACKED_ARRAY,
150 NumericArray = WXF_NUMERIC_ARRAY,
152 Association = WXF_ASSOCIATION,
154 Rule = WXF_RULE,
156 RuleDelayed = WXF_RULE_DELAYED,
158}
159
160impl ExpressionEnum {
161 pub fn name(self) -> &'static str {
164 token_to_name(self as u8)
165 }
166}
167#[derive(
173 Debug,
174 Copy,
175 Clone,
176 PartialEq,
177 Eq,
178 PartialOrd,
179 Ord,
180 Hash,
181 num_enum::TryFromPrimitive
182)]
183#[repr(u8)]
184pub enum NumericArrayEnum {
185 Integer8 = WXF_ARRAY_INTEGER8,
187 Integer16 = WXF_ARRAY_INTEGER16,
189 Integer32 = WXF_ARRAY_INTEGER32,
191 Integer64 = WXF_ARRAY_INTEGER64,
193 UnsignedInteger8 = WXF_ARRAY_UNSIGNED_INTEGER8,
195 UnsignedInteger16 = WXF_ARRAY_UNSIGNED_INTEGER16,
197 UnsignedInteger32 = WXF_ARRAY_UNSIGNED_INTEGER32,
199 UnsignedInteger64 = WXF_ARRAY_UNSIGNED_INTEGER64,
201 Real32 = WXF_ARRAY_REAL32,
203 Real64 = WXF_ARRAY_REAL64,
205 ComplexReal32 = WXF_ARRAY_COMPLEX_REAL32,
207 ComplexReal64 = WXF_ARRAY_COMPLEX_REAL64,
209}
210
211impl NumericArrayEnum {
212 pub fn size_in_bytes(self) -> usize {
215 token_to_size_in_bytes(self as u8)
216 }
217
218 pub fn name(self) -> &'static str {
220 token_to_name(self as u8)
221 }
222}
223
224#[derive(
231 Debug,
232 Copy,
233 Clone,
234 PartialEq,
235 Eq,
236 PartialOrd,
237 Ord,
238 Hash,
239 num_enum::TryFromPrimitive
240)]
241#[repr(u8)]
242pub enum PackedArrayEnum {
243 Integer8 = WXF_ARRAY_INTEGER8,
245 Integer16 = WXF_ARRAY_INTEGER16,
247 Integer32 = WXF_ARRAY_INTEGER32,
249 Integer64 = WXF_ARRAY_INTEGER64,
251 Real32 = WXF_ARRAY_REAL32,
253 Real64 = WXF_ARRAY_REAL64,
255 ComplexReal32 = WXF_ARRAY_COMPLEX_REAL32,
257 ComplexReal64 = WXF_ARRAY_COMPLEX_REAL64,
259}
260
261impl PackedArrayEnum {
262 pub fn size_in_bytes(self) -> usize {
265 token_to_size_in_bytes(self as u8)
266 }
267
268 pub fn name(self) -> &'static str {
270 token_to_name(self as u8)
271 }
272}
273
274impl From<PackedArrayEnum> for NumericArrayEnum {
275 fn from(p: PackedArrayEnum) -> Self {
276 NumericArrayEnum::try_from(p as u8)
277 .expect("PackedArrayEnum byte is always valid NumericArrayEnum")
278 }
279}
280
281impl TryFrom<NumericArrayEnum> for PackedArrayEnum {
282 type Error = ();
283 fn try_from(n: NumericArrayEnum) -> Result<Self, ()> {
284 PackedArrayEnum::try_from(n as u8).map_err(|_| ())
285 }
286}
287
288#[cfg(test)]
289mod tests {
290 use super::*;
291 use std::convert::TryFrom;
292
293 #[test]
294 fn expression_enum_try_from_known() {
295 assert_eq!(
296 ExpressionEnum::try_from(WXF_ASSOCIATION),
297 Ok(ExpressionEnum::Association)
298 );
299 }
300
301 #[test]
302 fn expression_enum_try_from_invalid() {
303 assert!(ExpressionEnum::try_from(0xFF_u8).is_err());
304 }
305
306 #[test]
307 fn numeric_array_enum_try_from_known() {
308 assert_eq!(
309 NumericArrayEnum::try_from(WXF_ARRAY_INTEGER32),
310 Ok(NumericArrayEnum::Integer32)
311 );
312 }
313
314 #[test]
315 fn numeric_array_enum_try_from_invalid() {
316 assert!(NumericArrayEnum::try_from(0xFF_u8).is_err());
317 }
318
319 #[test]
320 fn packed_array_enum_rejects_unsigned() {
321 assert!(PackedArrayEnum::try_from(WXF_ARRAY_UNSIGNED_INTEGER8).is_err());
322 }
323
324 #[test]
325 fn packed_to_numeric_roundtrip() {
326 let p = PackedArrayEnum::Integer32;
327 let n = NumericArrayEnum::from(p);
328 assert_eq!(n, NumericArrayEnum::Integer32);
329 }
330}