1#![allow(missing_docs)]
6
7use 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,
109 Separator = WXF_HEADER_SEPARATOR,
110 Compress = WXF_HEADER_COMPRESS,
111}
112
113#[derive(Debug, Copy, Clone, PartialEq, Eq, num_enum::TryFromPrimitive)]
119#[repr(u8)]
120pub enum ExpressionEnum {
121 Function = WXF_FUNCTION,
122 Symbol = WXF_SYMBOL,
123 String = WXF_STRING,
124 ByteArray = WXF_BYTE_ARRAY,
125 Integer8 = WXF_INTEGER8,
126 Integer16 = WXF_INTEGER16,
127 Integer32 = WXF_INTEGER32,
128 Integer64 = WXF_INTEGER64,
129 Real64 = WXF_REAL64,
130 BigInteger = WXF_BIG_INTEGER,
131 BigReal = WXF_BIG_REAL,
132 PackedArray = WXF_PACKED_ARRAY,
133 NumericArray = WXF_NUMERIC_ARRAY,
134 Association = WXF_ASSOCIATION,
135 Rule = WXF_RULE,
136 RuleDelayed = WXF_RULE_DELAYED,
137}
138
139impl ExpressionEnum {
140 pub fn name(self) -> &'static str {
141 token_to_name(self as u8)
142 }
143}
144#[derive(
150 Debug,
151 Copy,
152 Clone,
153 PartialEq,
154 Eq,
155 PartialOrd,
156 Ord,
157 Hash,
158 num_enum::TryFromPrimitive
159)]
160#[repr(u8)]
161pub enum NumericArrayEnum {
162 Integer8 = WXF_ARRAY_INTEGER8,
163 Integer16 = WXF_ARRAY_INTEGER16,
164 Integer32 = WXF_ARRAY_INTEGER32,
165 Integer64 = WXF_ARRAY_INTEGER64,
166 UnsignedInteger8 = WXF_ARRAY_UNSIGNED_INTEGER8,
167 UnsignedInteger16 = WXF_ARRAY_UNSIGNED_INTEGER16,
168 UnsignedInteger32 = WXF_ARRAY_UNSIGNED_INTEGER32,
169 UnsignedInteger64 = WXF_ARRAY_UNSIGNED_INTEGER64,
170 Real32 = WXF_ARRAY_REAL32,
171 Real64 = WXF_ARRAY_REAL64,
172 ComplexReal32 = WXF_ARRAY_COMPLEX_REAL32,
173 ComplexReal64 = WXF_ARRAY_COMPLEX_REAL64,
174}
175
176impl NumericArrayEnum {
177 pub fn size_in_bytes(self) -> usize {
178 token_to_size_in_bytes(self as u8)
179 }
180
181 pub fn name(self) -> &'static str {
182 token_to_name(self as u8)
183 }
184}
185
186#[derive(
193 Debug,
194 Copy,
195 Clone,
196 PartialEq,
197 Eq,
198 PartialOrd,
199 Ord,
200 Hash,
201 num_enum::TryFromPrimitive
202)]
203#[repr(u8)]
204pub enum PackedArrayEnum {
205 Integer8 = WXF_ARRAY_INTEGER8,
206 Integer16 = WXF_ARRAY_INTEGER16,
207 Integer32 = WXF_ARRAY_INTEGER32,
208 Integer64 = WXF_ARRAY_INTEGER64,
209 Real32 = WXF_ARRAY_REAL32,
210 Real64 = WXF_ARRAY_REAL64,
211 ComplexReal32 = WXF_ARRAY_COMPLEX_REAL32,
212 ComplexReal64 = WXF_ARRAY_COMPLEX_REAL64,
213}
214
215impl PackedArrayEnum {
216 pub fn size_in_bytes(self) -> usize {
217 token_to_size_in_bytes(self as u8)
218 }
219
220 pub fn name(self) -> &'static str {
221 token_to_name(self as u8)
222 }
223}
224
225impl From<PackedArrayEnum> for NumericArrayEnum {
226 fn from(p: PackedArrayEnum) -> Self {
227 NumericArrayEnum::try_from(p as u8)
228 .expect("PackedArrayEnum byte is always valid NumericArrayEnum")
229 }
230}
231
232impl TryFrom<NumericArrayEnum> for PackedArrayEnum {
233 type Error = ();
234 fn try_from(n: NumericArrayEnum) -> Result<Self, ()> {
235 PackedArrayEnum::try_from(n as u8).map_err(|_| ())
236 }
237}
238
239#[cfg(test)]
240mod tests {
241 use super::*;
242 use std::convert::TryFrom;
243
244 #[test]
245 fn expression_enum_try_from_known() {
246 assert_eq!(
247 ExpressionEnum::try_from(WXF_ASSOCIATION),
248 Ok(ExpressionEnum::Association)
249 );
250 }
251
252 #[test]
253 fn expression_enum_try_from_invalid() {
254 assert!(ExpressionEnum::try_from(0xFF_u8).is_err());
255 }
256
257 #[test]
258 fn numeric_array_enum_try_from_known() {
259 assert_eq!(
260 NumericArrayEnum::try_from(WXF_ARRAY_INTEGER32),
261 Ok(NumericArrayEnum::Integer32)
262 );
263 }
264
265 #[test]
266 fn numeric_array_enum_try_from_invalid() {
267 assert!(NumericArrayEnum::try_from(0xFF_u8).is_err());
268 }
269
270 #[test]
271 fn packed_array_enum_rejects_unsigned() {
272 assert!(PackedArrayEnum::try_from(WXF_ARRAY_UNSIGNED_INTEGER8).is_err());
273 }
274
275 #[test]
276 fn packed_to_numeric_roundtrip() {
277 let p = PackedArrayEnum::Integer32;
278 let n = NumericArrayEnum::from(p);
279 assert_eq!(n, NumericArrayEnum::Integer32);
280 }
281}