Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_jdat/src/macros.rs

49.0 KiB, 325 runs

created by r1870400018:475, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1#[macro_export]
2/// Create a `Dat` with automatic `Kind` detection using `std::convert::From` conversion.
3///
4/// ```
5/// use oxedyne_fe2o3_jdat::prelude::*;
6///
7/// let dat = dat!( 1u8 );
8/// ```
9macro_rules! dat {
10 ( $v:expr ) => {
11 Dat::from($v)
12 };
13}
14
15#[macro_export]
16/// Create an annotated `Dat` with automatic `Kind` detection using `std::convert::From` conversion.
17///
18/// ```
19/// use oxedyne_fe2o3_jdat::prelude::*;
20///
21/// let dat = abox!( 1u8, "A type1 comment" );
22/// ```
23macro_rules! abox {
24 ( $v:expr, $($arg:tt)*) => {
25 Dat::ABox(oxedyne_fe2o3_jdat::note::NoteConfig::default(), Box::new(Dat::from($v)), format!($($arg)*))
26 };
27}
28
29#[macro_export]
30/// Create a `Dat` with automatic `Kind` detection using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
31///
32/// ```
33/// use oxedyne_fe2o3_jdat::prelude::*;
34///
35/// let dat = best_dat!( 1u8 );
36/// ```
37macro_rules! best_dat {
38 ( $v:expr ) => {
39 Dat::best_from($v)
40 };
41}
42
43#[macro_export]
44/// Create a `List` of `Dat`s using `std::convert::From` conversion.
45///
46/// ```
47/// use oxedyne_fe2o3_jdat::prelude::*;
48///
49/// let list = listdat![ 1u8, 2u16, "value", -3i32, ];
50/// ```
51macro_rules! listdat {
52 { $( $x:expr ),* $(,)* } => {
53 {
54 let mut vec = Vec::new();
55 $(
56 vec.push(Dat::from($x));
57 )*
58 Dat::List(vec)
59 }
60 };
61}
62
63#[macro_export]
64/// Create a `List` of `Dat`s using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
65///
66/// ```
67/// use oxedyne_fe2o3_jdat::prelude::*;
68///
69/// let list = best_listdat![ 1u8, 2u16, "value", -3i32, ];
70/// ```
71macro_rules! best_listdat {
72 { $( $x:expr ),* $(,)* } => {
73 {
74 let mut vec = Vec::new();
75 $(
76 vec.push(Dat::best_from($x));
77 )*
78 Dat::List(vec)
79 }
80 };
81}
82
83#[macro_export]
84/// Create a `Dat::Tup2` using `std::convert::From` conversion.
85///
86/// ```
87/// use oxedyne_fe2o3_jdat::prelude::*;
88/// use oxedyne_fe2o3_jdat::tup2dat;
89///
90/// let expected = Dat::Tup2(Box::new([ dat!(1u8), dat!(2u8) ]));
91/// let list2 = tup2dat![ 1u8, 2u8, ];
92/// assert_eq!(list2, expected);
93/// ```
94macro_rules! tup2dat {
95
96 ( $e1:expr, $e2:expr $(,)? ) => {
97 Dat::Tup2(Box::new([
98 Dat::from($e1),
99 Dat::from($e2),
100 ]))
101 }
102}
103
104#[macro_export]
105/// Create a `Dat::Tup2` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
106///
107/// ```
108/// use oxedyne_fe2o3_jdat::prelude::*;
109/// use oxedyne_fe2o3_jdat::tup2dat;
110///
111/// let expected = Dat::Tup2(Box::new([ dat!(1u8), dat!(2u8) ]));
112/// let list2 = tup2dat![ 1u8, 2u8, ];
113/// assert_eq!(list2, expected);
114/// ```
115macro_rules! best_tup2dat {
116
117 ( $e1:expr, $e2:expr $(,)? ) => {
118 Dat::Tup2(Box::new([
119 Dat::best_from($e1),
120 Dat::best_from($e2),
121 ]))
122 }
123}
124
125#[macro_export]
126/// Create a `Dat::Tup3` using `std::convert::From` conversion.
127///
128/// ```
129/// use oxedyne_fe2o3_jdat::prelude::*;
130/// use oxedyne_fe2o3_jdat::tup3dat;
131/// use oxedyne_fe2o3_jdat::Dat;
132///
133/// let expected = Dat::Tup3(Box::new([
134/// dat!(1u8),
135/// dat!(2u8),
136/// dat!(3u8),
137/// ]));
138/// let list3 = tup3dat![ 1u8, 2u8, 3u8, ];
139/// assert_eq!(list3, expected);
140/// ```
141macro_rules! tup3dat {
142
143 ( $e1:expr, $e2:expr, $e3:expr $(,)? ) => {
144 Dat::Tup3(Box::new([
145 Dat::from($e1),
146 Dat::from($e2),
147 Dat::from($e3),
148 ]))
149 }
150}
151
152#[macro_export]
153/// Create a `Dat::Tup3` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
154///
155/// ```
156/// use oxedyne_fe2o3_jdat::prelude::*;
157/// use oxedyne_fe2o3_jdat::tup3dat;
158/// use oxedyne_fe2o3_jdat::Dat;
159///
160/// let expected = Dat::Tup3(Box::new([
161/// dat!(1u8),
162/// dat!(2u8),
163/// dat!(3u8),
164/// ]));
165/// let list3 = tup3dat![ 1u8, 2u8, 3u8, ];
166/// assert_eq!(list3, expected);
167/// ```
168macro_rules! best_tup3dat {
169
170 ( $e1:expr, $e2:expr, $e3:expr $(,)? ) => {
171 Dat::Tup3(Box::new([
172 Dat::best_from($e1),
173 Dat::best_from($e2),
174 Dat::best_from($e3),
175 ]))
176 }
177}
178
179#[macro_export]
180/// Create a `Dat::Tup4` using `std::convert::From` conversion.
181///
182/// ```
183/// use oxedyne_fe2o3_jdat::prelude::*;
184/// use oxedyne_fe2o3_jdat::tup4dat;
185/// use oxedyne_fe2o3_jdat::Dat;
186///
187/// let expected = Dat::Tup4(Box::new([
188/// dat!(1u8),
189/// dat!(2u8),
190/// dat!(3u8),
191/// dat!(4u8),
192/// ]));
193/// let list4 = tup4dat![ 1u8, 2u8, 3u8, 4u8, ];
194/// assert_eq!(list4, expected);
195/// ```
196macro_rules! tup4dat {
197
198 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr $(,)? ) => {
199 Dat::Tup4(Box::new([
200 Dat::from($e1),
201 Dat::from($e2),
202 Dat::from($e3),
203 Dat::from($e4),
204 ]))
205 }
206}
207
208#[macro_export]
209/// Create a `Dat::Tup4` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
210///
211/// ```
212/// use oxedyne_fe2o3_jdat::prelude::*;
213/// use oxedyne_fe2o3_jdat::tup4dat;
214/// use oxedyne_fe2o3_jdat::Dat;
215///
216/// let expected = Dat::Tup4(Box::new([
217/// dat!(1u8),
218/// dat!(2u8),
219/// dat!(3u8),
220/// dat!(4u8),
221/// ]));
222/// let list4 = tup4dat![ 1u8, 2u8, 3u8, 4u8, ];
223/// assert_eq!(list4, expected);
224/// ```
225macro_rules! best_tup4dat {
226
227 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr $(,)? ) => {
228 Dat::Tup4(Box::new([
229 Dat::best_from($e1),
230 Dat::best_from($e2),
231 Dat::best_from($e3),
232 Dat::best_from($e4),
233 ]))
234 }
235}
236
237#[macro_export]
238/// Create a `Dat::Tup5` using `std::convert::From` conversion.
239///
240/// ```
241/// use oxedyne_fe2o3_jdat::prelude::*;
242/// use oxedyne_fe2o3_jdat::tup5dat;
243/// use oxedyne_fe2o3_jdat::Dat;
244///
245/// let expected = Dat::Tup5(Box::new([
246/// dat!(1u8),
247/// dat!(2u8),
248/// dat!(3u8),
249/// dat!(4u8),
250/// dat!(5u8),
251/// ]));
252/// let list5 = tup5dat![ 1u8, 2u8, 3u8, 4u8, 5u8, ];
253/// assert_eq!(list5, expected);
254/// ```
255macro_rules! tup5dat {
256
257 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr $(,)? ) => {
258 Dat::Tup5(Box::new([
259 Dat::from($e1),
260 Dat::from($e2),
261 Dat::from($e3),
262 Dat::from($e4),
263 Dat::from($e5),
264 ]))
265 }
266}
267
268#[macro_export]
269/// Create a `Dat::Tup5` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
270///
271/// ```
272/// use oxedyne_fe2o3_jdat::prelude::*;
273/// use oxedyne_fe2o3_jdat::tup5dat;
274/// use oxedyne_fe2o3_jdat::Dat;
275///
276/// let expected = Dat::Tup5(Box::new([
277/// dat!(1u8),
278/// dat!(2u8),
279/// dat!(3u8),
280/// dat!(4u8),
281/// dat!(5u8),
282/// ]));
283/// let list5 = tup5dat![ 1u8, 2u8, 3u8, 4u8, 5u8, ];
284/// assert_eq!(list5, expected);
285/// ```
286macro_rules! best_tup5dat {
287
288 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr $(,)? ) => {
289 Dat::Tup5(Box::new([
290 Dat::best_from($e1),
291 Dat::best_from($e2),
292 Dat::best_from($e3),
293 Dat::best_from($e4),
294 Dat::best_from($e5),
295 ]))
296 }
297}
298
299#[macro_export]
300/// Create a `Dat::Tup6` using `std::convert::From` conversion.
301///
302/// ```
303/// use oxedyne_fe2o3_jdat::prelude::*;
304/// use oxedyne_fe2o3_jdat::tup6dat;
305/// use oxedyne_fe2o3_jdat::Dat;
306///
307/// let expected = Dat::Tup6(Box::new([
308/// dat!(1u8),
309/// dat!(2u8),
310/// dat!(3u8),
311/// dat!(4u8),
312/// dat!(5u8),
313/// dat!(6u8),
314/// ]));
315/// let list6 = tup6dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, ];
316/// assert_eq!(list6, expected);
317/// ```
318macro_rules! tup6dat {
319
320 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
321 $e6:expr $(,)? ) => {
322 Dat::Tup6(Box::new([
323 Dat::from($e1),
324 Dat::from($e2),
325 Dat::from($e3),
326 Dat::from($e4),
327 Dat::from($e5),
328 Dat::from($e6),
329 ]))
330 }
331}
332
333#[macro_export]
334/// Create a `Dat::Tup6` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
335///
336/// ```
337/// use oxedyne_fe2o3_jdat::prelude::*;
338/// use oxedyne_fe2o3_jdat::tup6dat;
339/// use oxedyne_fe2o3_jdat::Dat;
340///
341/// let expected = Dat::Tup6(Box::new([
342/// dat!(1u8),
343/// dat!(2u8),
344/// dat!(3u8),
345/// dat!(4u8),
346/// dat!(5u8),
347/// dat!(6u8),
348/// ]));
349/// let list6 = tup6dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, ];
350/// assert_eq!(list6, expected);
351/// ```
352macro_rules! best_tup6dat {
353
354 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
355 $e6:expr $(,)? ) => {
356 Dat::Tup6(Box::new([
357 Dat::best_from($e1),
358 Dat::best_from($e2),
359 Dat::best_from($e3),
360 Dat::best_from($e4),
361 Dat::best_from($e5),
362 Dat::best_from($e6),
363 ]))
364 }
365}
366
367#[macro_export]
368/// Create a `Dat::Tup7` using `std::convert::From` conversion.
369///
370/// ```
371/// use oxedyne_fe2o3_jdat::prelude::*;
372/// use oxedyne_fe2o3_jdat::tup7dat;
373/// use oxedyne_fe2o3_jdat::Dat;
374///
375/// let expected = Dat::Tup7(Box::new([
376/// dat!(1u8),
377/// dat!(2u8),
378/// dat!(3u8),
379/// dat!(4u8),
380/// dat!(5u8),
381/// dat!(6u8),
382/// dat!(7u8),
383/// ]));
384/// let list7 = tup7dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, ];
385/// assert_eq!(list7, expected);
386/// ```
387macro_rules! tup7dat {
388
389 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
390 $e6:expr, $e7:expr $(,)? ) => {
391 Dat::Tup7(Box::new([
392 Dat::from($e1),
393 Dat::from($e2),
394 Dat::from($e3),
395 Dat::from($e4),
396 Dat::from($e5),
397 Dat::from($e6),
398 Dat::from($e7),
399 ]))
400 }
401}
402
403#[macro_export]
404/// Create a `Dat::Tup7` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
405///
406/// ```
407/// use oxedyne_fe2o3_jdat::prelude::*;
408/// use oxedyne_fe2o3_jdat::tup7dat;
409/// use oxedyne_fe2o3_jdat::Dat;
410///
411/// let expected = Dat::Tup7(Box::new([
412/// dat!(1u8),
413/// dat!(2u8),
414/// dat!(3u8),
415/// dat!(4u8),
416/// dat!(5u8),
417/// dat!(6u8),
418/// dat!(7u8),
419/// ]));
420/// let list7 = tup7dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, ];
421/// assert_eq!(list7, expected);
422/// ```
423macro_rules! best_tup7dat {
424
425 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
426 $e6:expr, $e7:expr $(,)? ) => {
427 Dat::Tup7(Box::new([
428 Dat::best_from($e1),
429 Dat::best_from($e2),
430 Dat::best_from($e3),
431 Dat::best_from($e4),
432 Dat::best_from($e5),
433 Dat::best_from($e6),
434 Dat::best_from($e7),
435 ]))
436 }
437}
438
439#[macro_export]
440/// Create a `Dat::Tup8` using `std::convert::From` conversion.
441///
442/// ```
443/// use oxedyne_fe2o3_jdat::prelude::*;
444/// use oxedyne_fe2o3_jdat::tup8dat;
445/// use oxedyne_fe2o3_jdat::Dat;
446///
447/// let expected = Dat::Tup8(Box::new([
448/// dat!(1u8),
449/// dat!(2u8),
450/// dat!(3u8),
451/// dat!(4u8),
452/// dat!(5u8),
453/// dat!(6u8),
454/// dat!(7u8),
455/// dat!(8u8),
456/// ]));
457/// let list8 = tup8dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, ];
458/// assert_eq!(list8, expected);
459/// ```
460macro_rules! tup8dat {
461
462 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
463 $e6:expr, $e7:expr, $e8:expr $(,)? ) => {
464 Dat::Tup8(Box::new([
465 Dat::from($e1),
466 Dat::from($e2),
467 Dat::from($e3),
468 Dat::from($e4),
469 Dat::from($e5),
470 Dat::from($e6),
471 Dat::from($e7),
472 Dat::from($e8),
473 ]))
474 }
475}
476
477#[macro_export]
478/// Create a `Dat::Tup8` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
479///
480/// ```
481/// use oxedyne_fe2o3_jdat::prelude::*;
482/// use oxedyne_fe2o3_jdat::tup8dat;
483/// use oxedyne_fe2o3_jdat::Dat;
484///
485/// let expected = Dat::Tup8(Box::new([
486/// dat!(1u8),
487/// dat!(2u8),
488/// dat!(3u8),
489/// dat!(4u8),
490/// dat!(5u8),
491/// dat!(6u8),
492/// dat!(7u8),
493/// dat!(8u8),
494/// ]));
495/// let list8 = tup8dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, ];
496/// assert_eq!(list8, expected);
497/// ```
498macro_rules! best_tup8dat {
499
500 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
501 $e6:expr, $e7:expr, $e8:expr $(,)? ) => {
502 Dat::Tup8(Box::new([
503 Dat::best_from($e1),
504 Dat::best_from($e2),
505 Dat::best_from($e3),
506 Dat::best_from($e4),
507 Dat::best_from($e5),
508 Dat::best_from($e6),
509 Dat::best_from($e7),
510 Dat::best_from($e8),
511 ]))
512 }
513}
514
515#[macro_export]
516/// Create a `Dat::Tup9` using `std::convert::From` conversion.
517///
518/// ```
519/// use oxedyne_fe2o3_jdat::prelude::*;
520/// use oxedyne_fe2o3_jdat::tup9dat;
521/// use oxedyne_fe2o3_jdat::Dat;
522///
523/// let expected = Dat::Tup9(Box::new([
524/// dat!(1u8),
525/// dat!(2u8),
526/// dat!(3u8),
527/// dat!(4u8),
528/// dat!(5u8),
529/// dat!(6u8),
530/// dat!(7u8),
531/// dat!(8u8),
532/// dat!(9u8),
533/// ]));
534/// let list9 = tup9dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, ];
535/// assert_eq!(list9, expected);
536/// ```
537macro_rules! tup9dat {
538
539 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
540 $e6:expr, $e7:expr, $e8:expr, $e9:expr $(,)? ) => {
541 Dat::Tup9(Box::new([
542 Dat::from($e1),
543 Dat::from($e2),
544 Dat::from($e3),
545 Dat::from($e4),
546 Dat::from($e5),
547 Dat::from($e6),
548 Dat::from($e7),
549 Dat::from($e8),
550 Dat::from($e9),
551 ]))
552 }
553}
554
555#[macro_export]
556/// Create a `Dat::Tup9` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
557///
558/// ```
559/// use oxedyne_fe2o3_jdat::prelude::*;
560/// use oxedyne_fe2o3_jdat::tup9dat;
561/// use oxedyne_fe2o3_jdat::Dat;
562///
563/// let expected = Dat::Tup9(Box::new([
564/// dat!(1u8),
565/// dat!(2u8),
566/// dat!(3u8),
567/// dat!(4u8),
568/// dat!(5u8),
569/// dat!(6u8),
570/// dat!(7u8),
571/// dat!(8u8),
572/// dat!(9u8),
573/// ]));
574/// let list9 = tup9dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, ];
575/// assert_eq!(list9, expected);
576/// ```
577macro_rules! best_tup9dat {
578
579 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
580 $e6:expr, $e7:expr, $e8:expr, $e9:expr $(,)? ) => {
581 Dat::Tup9(Box::new([
582 Dat::best_from($e1),
583 Dat::best_from($e2),
584 Dat::best_from($e3),
585 Dat::best_from($e4),
586 Dat::best_from($e5),
587 Dat::best_from($e6),
588 Dat::best_from($e7),
589 Dat::best_from($e8),
590 Dat::best_from($e9),
591 ]))
592 }
593}
594
595#[macro_export]
596/// Create a `Dat::Tup10` using `std::convert::From` conversion.
597///
598/// ```
599/// use oxedyne_fe2o3_jdat::prelude::*;
600/// use oxedyne_fe2o3_jdat::tup10dat;
601/// use oxedyne_fe2o3_jdat::Dat;
602///
603/// let expected = Dat::Tup10(Box::new([
604/// dat!(1u8),
605/// dat!(2u8),
606/// dat!(3u8),
607/// dat!(4u8),
608/// dat!(5u8),
609/// dat!(6u8),
610/// dat!(7u8),
611/// dat!(8u8),
612/// dat!(9u8),
613/// dat!(10u8),
614/// ]));
615/// let list10 = tup10dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, ];
616/// assert_eq!(list10, expected);
617/// ```
618macro_rules! tup10dat {
619
620 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
621 $e6:expr, $e7:expr, $e8:expr, $e9:expr, $e10:expr $(,)? ) => {
622 Dat::Tup10(Box::new([
623 Dat::from($e1),
624 Dat::from($e2),
625 Dat::from($e3),
626 Dat::from($e4),
627 Dat::from($e5),
628 Dat::from($e6),
629 Dat::from($e7),
630 Dat::from($e8),
631 Dat::from($e9),
632 Dat::from($e10),
633 ]))
634 }
635}
636
637#[macro_export]
638/// Create a `Dat::Tup10` using `oxedyne_fe2o3_core::conv::BestFrom` conversion.
639///
640/// ```
641/// use oxedyne_fe2o3_jdat::prelude::*;
642/// use oxedyne_fe2o3_jdat::tup10dat;
643/// use oxedyne_fe2o3_jdat::Dat;
644///
645/// let expected = Dat::Tup10(Box::new([
646/// dat!(1u8),
647/// dat!(2u8),
648/// dat!(3u8),
649/// dat!(4u8),
650/// dat!(5u8),
651/// dat!(6u8),
652/// dat!(7u8),
653/// dat!(8u8),
654/// dat!(9u8),
655/// dat!(10u8),
656/// ]));
657/// let list10 = tup10dat![ 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, ];
658/// assert_eq!(list10, expected);
659/// ```
660macro_rules! best_tup10dat {
661
662 ( $e1:expr, $e2:expr, $e3:expr, $e4:expr, $e5:expr,
663 $e6:expr, $e7:expr, $e8:expr, $e9:expr, $e10:expr $(,)? ) => {
664 Dat::Tup10(Box::new([
665 Dat::best_from($e1),
666 Dat::best_from($e2),
667 Dat::best_from($e3),
668 Dat::best_from($e4),
669 Dat::best_from($e5),
670 Dat::best_from($e6),
671 Dat::best_from($e7),
672 Dat::best_from($e8),
673 Dat::best_from($e9),
674 Dat::best_from($e10),
675 ]))
676 }
677}
678
679#[macro_export]
680/// Create a `Map` of `Dat`s.
681///
682/// ```
683/// use oxedyne_fe2o3_core::prelude::*;
684/// use oxedyne_fe2o3_jdat::prelude::*; // create_dat_map must be brought into scope
685///
686/// fn main() {
687/// let map = mapdat![
688/// 1u8 => 2u16,
689/// "key" => -3i32,
690/// ];
691/// }
692/// ```
693macro_rules! mapdat {
694 { $( $k:expr => $v:expr ),* $(,)* } => {
695 {
696 let mut pairs = Vec::new();
697 $(
698 pairs.push((Dat::from($k), Dat::from($v)));
699 )*
700 create_dat_map(pairs)
701 }
702 };
703}
704
705#[macro_export]
706/// Similar to `mapdat` except an order-preserving `Dat::OrdMap` is returned.
707macro_rules! omapdat {
708 { $( $k:expr => $v:expr ),* $(,)* } => {
709 {
710 let mut pairs = Vec::new();
711 $(
712 pairs.push((Dat::from($k), Dat::from($v)));
713 )*
714 create_dat_ordmap(pairs)
715 }
716 };
717}
718
719#[macro_export]
720macro_rules! best_mapdat {
721 { $( $k:expr => $v:expr ),* $(,)* } => {
722 {
723 //use crate::create_dat_map;
724 let mut pairs = Vec::new();
725 $(
726 pairs.push((Dat::best_from($k), Dat::best_from($v)));
727 )*
728 create_dat_map(pairs)
729 }
730 };
731}
732
733#[macro_export]
734macro_rules! best_omapdat {
735 { $( $k:expr => $v:expr ),* $(,)* } => {
736 {
737 //use crate::create_dat_map;
738 let mut pairs = Vec::new();
739 $(
740 pairs.push((Dat::best_from($k), Dat::best_from($v)));
741 )*
742 create_dat_ordmap(pairs)
743 }
744 };
745}
746
747#[macro_export]
748/// Extracts associated data from a `Dat`. The motivating purpose was to extract the
749/// associated `Vec<u8>` encapsulated using `Dat::bytdat`. This uses flexible, but still
750/// fixed, encoding for the length, yielding a either a `Dat::BU8` through to a
751/// `Dat::BU64`.
752/// ```
753/// use oxedyne_fe2o3_core::prelude::*;
754/// use oxedyne_fe2o3_jdat::prelude::*;
755/// use oxedyne_fe2o3_jdat::try_extract_dat;
756///
757/// fn main() -> Outcome<()> { // needed because try_extract_dat! can return Err
758/// let v1 = vec![1u8, 2, 3, 4];
759/// let d2 = Dat::bytdat(v1.clone());
760/// let v2 = try_extract_dat!(d2, BU8, BU16, BU32, BU64);
761/// assert_eq!(v1.len(), v2.len());
762/// for (i, v) in v1.into_iter().enumerate() {
763/// assert_eq!(v, v2[i]);
764/// }
765/// Ok(())
766/// }
767/// ```
768macro_rules! try_extract_dat {
769 { $src:expr, $($var:ident),* $(,)* } => {
770 match $src {
771 $(
772 Dat::$var(v) => v,
773 )*
774 unknown => return Err(err!(
775 "Expected one of a {} found {:?}.",
776 stringify!($(Dat::$var,)*), unknown;
777 Daticle, Input, Invalid)),
778 }
779 };
780}
781
782#[macro_export]
783/// Extracts associated data from a `Dat`, including a specified cast to a type alias for
784/// multiple source variants.
785/// ```
786/// use oxedyne_fe2o3_core::prelude::*;
787/// use oxedyne_fe2o3_jdat::prelude::*;
788/// use oxedyne_fe2o3_jdat::try_extract_dat_as;
789///
790/// type AnIntType = u32;
791///
792/// fn main() -> Outcome<()> { // needed because try_extract_dat! can return Err
793/// let n1 = 42u8 as AnIntType;
794/// let d1 = dat!(n1);
795/// let n2 = try_extract_dat_as!(d1, AnIntType, U16, U32, U64);
796/// // An alternative here is to use:
797/// //let n2 = try_extract_dat!(d1, U32) as AnIntType;
798/// // but rather than a single change of `AnIntType` to a `u64`, we would also need to change
799/// // this `try_extract_dat!` call.
800/// assert_eq!(n1, n2);
801/// Ok(())
802/// }
803/// ```
804macro_rules! try_extract_dat_as {
805 { $src:expr, $trg:ty, $( $var:ident ),* $(,)* } => {
806 match $src {
807 $(
808 Dat::$var(v) => v as $trg,
809 )*
810 unknown => return Err(err!(
811 "Expected a {} found {:?}.",
812 stringify!($(Dat::$var,)*), unknown;
813 Daticle, Input, Invalid)),
814 }
815 };
816}
817
818#[macro_export]
819/// Extracts associated `Vec` from a `Dat::List`.
820/// ```
821/// use oxedyne_fe2o3_core::prelude::*;
822/// use oxedyne_fe2o3_jdat::prelude::*;
823/// use oxedyne_fe2o3_jdat::try_extract_listdat;
824///
825/// fn main() -> Outcome<()> { // needed because try_extract_listdat! can return Err
826/// let list = listdat![42u8, "hello"];
827/// let v = try_extract_listdat!(list, 2);
828/// assert_eq!(v, vec![dat!(42u8), dat!("hello")]);
829/// Ok(())
830/// }
831/// ```
832macro_rules! try_extract_listdat {
833 { $src:expr, $n:expr } => {
834 match $src {
835 Dat::List(v) => {
836 if v.len() == $n {
837 v
838 } else {
839 return Err(err!(
840 "Number of Dat::List items should be {}, found {}.",
841 $n, v.len();
842 Daticle, Input, Invalid));
843 }
844 },
845 unknown => return Err(err!(
846 "Expected a Dat::List, found {:?}.",
847 unknown;
848 Daticle, Input, Invalid)),
849 }
850 };
851}
852
853#[macro_export]
854/// Extracts associated `[Dat; 2]` from a `Dat::Tup2`.
855/// ```
856/// use oxedyne_fe2o3_core::prelude::*;
857/// use oxedyne_fe2o3_jdat::prelude::*;
858/// use oxedyne_fe2o3_jdat::try_extract_tup2dat;
859///
860/// fn main() -> Outcome<()> { // needed because try_extract_tup2dat! can return Err
861/// let array = [
862/// dat!("one"),
863/// dat!("two"),
864/// ];
865/// let list = Dat::Tup2(Box::new(array.clone()));
866/// let v = try_extract_tup2dat!(list);
867/// assert_eq!(v, array);
868/// Ok(())
869/// }
870/// ```
871macro_rules! try_extract_tup2dat {
872 { $src:expr } => {
873 match $src {
874 Dat::Tup2(v) => {
875 if v.len() == 2 {
876 *v
877 } else {
878 return Err(err!(
879 "Number of Dat::Tup2 items should be 2, found {}.", v.len();
880 Daticle, Input, Invalid));
881 }
882 },
883 unknown => return Err(err!(
884 "Expected a Dat::Tup2, found {:?}.",
885 unknown;
886 Daticle, Input, Invalid)),
887 }
888 };
889}
890
891#[macro_export]
892/// Extracts associated `[Dat; 3]` from a `Dat::Tup3`.
893/// ```
894/// use oxedyne_fe2o3_core::prelude::*;
895/// use oxedyne_fe2o3_jdat::prelude::*;
896/// use oxedyne_fe2o3_jdat::try_extract_tup3dat;
897///
898/// fn main() -> Outcome<()> { // needed because try_extract_tup3dat! can return Err
899/// let array = [
900/// dat!("one"),
901/// dat!("two"),
902/// dat!("three"),
903/// ];
904/// let list = Dat::Tup3(Box::new(array.clone()));
905/// let v = try_extract_tup3dat!(list);
906/// assert_eq!(v, array);
907/// Ok(())
908/// }
909/// ```
910macro_rules! try_extract_tup3dat {
911 { $src:expr } => {
912 match $src {
913 Dat::Tup3(v) => {
914 if v.len() == 3 {
915 *v
916 } else {
917 return Err(err!(
918 "Number of Dat::Tup3 items should be 3, found {}.", v.len();
919 Daticle, Input, Invalid));
920 }
921 },
922 unknown => return Err(err!(
923 "Expected a Dat::Tup3, found {:?}.",
924 unknown;
925 Daticle, Input, Invalid)),
926 }
927 };
928}
929
930#[macro_export]
931/// Extracts associated `[Dat; 4]` from a `Dat::Tup4`.
932/// ```
933/// use oxedyne_fe2o3_core::prelude::*;
934/// use oxedyne_fe2o3_jdat::prelude::*;
935/// use oxedyne_fe2o3_jdat::try_extract_tup4dat;
936///
937/// fn main() -> Outcome<()> { // needed because try_extract_tup4dat! can return Err
938/// let array = [
939/// dat!("one"),
940/// dat!("two"),
941/// dat!("three"),
942/// dat!("four"),
943/// ];
944/// let list = Dat::Tup4(Box::new(array.clone()));
945/// let v = try_extract_tup4dat!(list);
946/// assert_eq!(v, array);
947/// Ok(())
948/// }
949/// ```
950macro_rules! try_extract_tup4dat {
951 { $src:expr } => {
952 match $src {
953 Dat::Tup4(v) => {
954 if v.len() == 4 {
955 *v
956 } else {
957 return Err(err!(
958 "Number of Dat::Tup4 items should be 4, found {}.", v.len();
959 Daticle, Input, Invalid));
960 }
961 },
962 unknown => return Err(err!(
963 "Expected a Dat::Tup4, found {:?}.",
964 unknown;
965 Daticle, Input, Invalid)),
966 }
967 };
968}
969
970#[macro_export]
971/// Extracts associated `[Dat; 5]` from a `Dat::Tup5`.
972/// ```
973/// use oxedyne_fe2o3_core::prelude::*;
974/// use oxedyne_fe2o3_jdat::prelude::*;
975/// use oxedyne_fe2o3_jdat::try_extract_tup5dat;
976///
977/// fn main() -> Outcome<()> { // needed because try_extract_tup5dat! can return Err
978/// let array = [
979/// dat!("one"),
980/// dat!("two"),
981/// dat!("three"),
982/// dat!("four"),
983/// dat!("five"),
984/// ];
985/// let list = Dat::Tup5(Box::new(array.clone()));
986/// let v = try_extract_tup5dat!(list);
987/// assert_eq!(v, array);
988/// Ok(())
989/// }
990/// ```
991macro_rules! try_extract_tup5dat {
992 { $src:expr } => {
993 match $src {
994 Dat::Tup5(v) => {
995 if v.len() == 5 {
996 *v
997 } else {
998 return Err(err!(
999 "Number of Dat::Tup5 items should be 5, found {}.", v.len();
1000 Daticle, Input, Invalid));
1001 }
1002 },
1003 unknown => return Err(err!(
1004 "Expected a Dat::Tup5, found {:?}.",
1005 unknown;
1006 Daticle, Input, Invalid)),
1007 }
1008 };
1009}
1010
1011#[macro_export]
1012/// Extracts associated `[Dat; 6]` from a `Dat::Tup6`.
1013/// ```
1014/// use oxedyne_fe2o3_core::prelude::*;
1015/// use oxedyne_fe2o3_jdat::prelude::*;
1016/// use oxedyne_fe2o3_jdat::try_extract_tup6dat;
1017///
1018/// fn main() -> Outcome<()> { // needed because try_extract_tup6dat! can return Err
1019/// let array = [
1020/// dat!("one"),
1021/// dat!("two"),
1022/// dat!("three"),
1023/// dat!("four"),
1024/// dat!("five"),
1025/// dat!("six"),
1026/// ];
1027/// let list = Dat::Tup6(Box::new(array.clone()));
1028/// let v = try_extract_tup6dat!(list);
1029/// assert_eq!(v, array);
1030/// Ok(())
1031/// }
1032/// ```
1033macro_rules! try_extract_tup6dat {
1034 { $src:expr } => {
1035 match $src {
1036 Dat::Tup6(v) => {
1037 if v.len() == 6 {
1038 *v
1039 } else {
1040 return Err(err!(
1041 "Number of Dat::Tup6 items should be 6, found {}.", v.len();
1042 Daticle, Input, Invalid));
1043 }
1044 },
1045 unknown => return Err(err!(
1046 "Expected a Dat::Tup6, found {:?}.",
1047 unknown;
1048 Daticle, Input, Invalid)),
1049 }
1050 };
1051}
1052
1053#[macro_export]
1054/// Extracts associated `[Dat; 7]` from a `Dat::Tup7`.
1055/// ```
1056/// use oxedyne_fe2o3_core::prelude::*;
1057/// use oxedyne_fe2o3_jdat::prelude::*;
1058/// use oxedyne_fe2o3_jdat::try_extract_tup7dat;
1059///
1060/// fn main() -> Outcome<()> { // needed because try_extract_tup7dat! can return Err
1061/// let array = [
1062/// dat!("one"),
1063/// dat!("two"),
1064/// dat!("three"),
1065/// dat!("four"),
1066/// dat!("five"),
1067/// dat!("six"),
1068/// dat!("seven"),
1069/// ];
1070/// let list = Dat::Tup7(Box::new(array.clone()));
1071/// let v = try_extract_tup7dat!(list);
1072/// assert_eq!(v, array);
1073/// Ok(())
1074/// }
1075/// ```
1076macro_rules! try_extract_tup7dat {
1077 { $src:expr } => {
1078 match $src {
1079 Dat::Tup7(v) => {
1080 if v.len() == 7 {
1081 *v
1082 } else {
1083 return Err(err!(
1084 "Number of Dat::Tup7 items should be 7, found {}.", v.len();
1085 Daticle, Input, Invalid));
1086 }
1087 },
1088 unknown => return Err(err!(
1089 "Expected a Dat::Tup7, found {:?}.",
1090 unknown;
1091 Daticle, Input, Invalid)),
1092 }
1093 };
1094}
1095
1096#[macro_export]
1097/// Extracts associated `[Dat; 8]` from a `Dat::Tup8`.
1098/// ```
1099/// use oxedyne_fe2o3_core::prelude::*;
1100/// use oxedyne_fe2o3_jdat::prelude::*;
1101/// use oxedyne_fe2o3_jdat::try_extract_tup8dat;
1102///
1103/// fn main() -> Outcome<()> { // needed because try_extract_tup8dat! can return Err
1104/// let array = [
1105/// dat!("one"),
1106/// dat!("two"),
1107/// dat!("three"),
1108/// dat!("four"),
1109/// dat!("five"),
1110/// dat!("six"),
1111/// dat!("seven"),
1112/// dat!("eight"),
1113/// ];
1114/// let list = Dat::Tup8(Box::new(array.clone()));
1115/// let v = try_extract_tup8dat!(list);
1116/// assert_eq!(v, array);
1117/// Ok(())
1118/// }
1119/// ```
1120macro_rules! try_extract_tup8dat {
1121 { $src:expr } => {
1122 match $src {
1123 Dat::Tup8(v) => {
1124 if v.len() == 8 {
1125 *v
1126 } else {
1127 return Err(err!(
1128 "Number of Dat::Tup8 items should be 8, found {}.", v.len();
1129 Daticle, Input, Invalid));
1130 }
1131 },
1132 unknown => return Err(err!(
1133 "Expected a Dat::Tup8, found {:?}.",
1134 unknown;
1135 Daticle, Input, Invalid)),
1136 }
1137 };
1138}
1139
1140#[macro_export]
1141/// Extracts associated `[Dat; 9]` from a `Dat::Tup9`.
1142/// ```
1143/// use oxedyne_fe2o3_core::prelude::*;
1144/// use oxedyne_fe2o3_jdat::prelude::*;
1145/// use oxedyne_fe2o3_jdat::try_extract_tup9dat;
1146///
1147/// fn main() -> Outcome<()> { // needed because try_extract_tup9dat! can return Err
1148/// let array = [
1149/// dat!("one"),
1150/// dat!("two"),
1151/// dat!("three"),
1152/// dat!("four"),
1153/// dat!("five"),
1154/// dat!("six"),
1155/// dat!("seven"),
1156/// dat!("eight"),
1157/// dat!("nine"),
1158/// ];
1159/// let list = Dat::Tup9(Box::new(array.clone()));
1160/// let v = try_extract_tup9dat!(list);
1161/// assert_eq!(v, array);
1162/// Ok(())
1163/// }
1164/// ```
1165macro_rules! try_extract_tup9dat {
1166 { $src:expr } => {
1167 match $src {
1168 Dat::Tup9(v) => {
1169 if v.len() == 9 {
1170 *v
1171 } else {
1172 return Err(err!(
1173 "Number of Dat::Tup9 items should be 9, found {}.", v.len();
1174 Daticle, Input, Invalid));
1175 }
1176 },
1177 unknown => return Err(err!(
1178 "Expected a Dat::Tup9, found {:?}.",
1179 unknown;
1180 Daticle, Input, Invalid)),
1181 }
1182 };
1183}
1184
1185#[macro_export]
1186/// Extracts associated `[Dat; 10]` from a `Dat::Tup10`.
1187/// ```
1188/// use oxedyne_fe2o3_core::prelude::*;
1189/// use oxedyne_fe2o3_jdat::prelude::*;
1190/// use oxedyne_fe2o3_jdat::try_extract_tup10dat;
1191///
1192/// fn main() -> Outcome<()> { // needed because try_extract_tup10dat! can return Err
1193/// let array = [
1194/// dat!("one"),
1195/// dat!("two"),
1196/// dat!("three"),
1197/// dat!("four"),
1198/// dat!("five"),
1199/// dat!("six"),
1200/// dat!("seven"),
1201/// dat!("eight"),
1202/// dat!("nine"),
1203/// dat!("ten"),
1204/// ];
1205/// let list = Dat::Tup10(Box::new(array.clone()));
1206/// let v = try_extract_tup10dat!(list);
1207/// assert_eq!(v, array);
1208/// Ok(())
1209/// }
1210/// ```
1211macro_rules! try_extract_tup10dat {
1212 { $src:expr } => {
1213 match $src {
1214 Dat::Tup10(v) => {
1215 if v.len() == 10 {
1216 *v
1217 } else {
1218 return Err(err!(
1219 "Number of Dat::Tup10 items should be 10, found {}.", v.len();
1220 Daticle, Input, Invalid));
1221 }
1222 },
1223 unknown => return Err(err!(
1224 "Expected a Dat::Tup10, found {:?}.",
1225 unknown;
1226 Daticle, Input, Invalid)),
1227 }
1228 };
1229}
1230
1231#[macro_export]
1232/// Implement infallible, consuming `From` conversion to `Dat`, as well as fallible cloning `ToDat`
1233/// and consuming `FromDat`.
1234macro_rules! to_from_dat {
1235 { $t:ty, $v:ident } => {
1236
1237 impl From<$t> for Dat {
1238 fn from(x: $t) -> Self { Dat::$v(x) }
1239 }
1240 impl ToDat for $t {
1241 fn to_dat(&self) -> Outcome<Dat> { Ok(Dat::from(self.clone())) }
1242 }
1243 impl FromDat for $t {
1244 fn from_dat(dat: Dat) -> Outcome<Self> { Ok(try_extract_dat!(dat, $v)) }
1245 }
1246
1247 };
1248}
1249
1250#[macro_export]
1251/// Implement [`std::convert::From`] conversions to [`Dat`] variants using min-sizing.
1252macro_rules! best_from_int_to_dat {
1253 { $t:ty } => {
1254
1255 impl BestFrom<$t> for Dat {
1256 fn best_from(x: $t) -> Self {
1257 DatInt::from(x).min_size().as_dat()
1258 }
1259 }
1260
1261 };
1262}
1263
1264#[macro_export]
1265/// Implement [`std::convert::From`] boxed conversions to [`Dat`] variants.
1266macro_rules! to_from_dat_boxed {
1267 { $t:ty, $v:ident } => {
1268
1269 impl From<$t> for Dat {
1270 fn from(x: $t) -> Self {
1271 Dat::$v(Box::new(x))
1272 }
1273 }
1274
1275 };
1276}
1277
1278#[macro_export]
1279/// Provide a simple cloning getter for variants of an enum, primarily for the [`FromDatMap`] and
1280/// [`ToDatMap`] derive macros.
1281macro_rules! enum_getter {
1282 { $method:ident, $typ:ty, $variant:ident } => {
1283
1284 pub fn $method(&self) -> Option<$typ> {
1285 if let Self::$variant(v) = self {
1286 Some(v.clone())
1287 } else {
1288 None
1289 }
1290 }
1291
1292 };
1293}
1294
1295#[macro_export]
1296/// Coerce numercial types to the desired type primarily for the [`FromDatMap`] and [`ToDatMap`]
1297/// derive macros.
1298macro_rules! enum_getter_numeric {
1299 // For unsigned integers - can convert from smaller types
1300 { $method:ident, u8 } => {
1301 pub fn $method(&self) -> Option<u8> {
1302 match self {
1303 Self::U8(v) => Some(*v),
1304 _ => None,
1305 }
1306 }
1307 };
1308 { $method:ident, u16 } => {
1309 pub fn $method(&self) -> Option<u16> {
1310 match self {
1311 Self::U8(v) => Some(*v as u16),
1312 Self::U16(v) => Some(*v),
1313 _ => None,
1314 }
1315 }
1316 };
1317 { $method:ident, u32 } => {
1318 pub fn $method(&self) -> Option<u32> {
1319 match self {
1320 Self::U8(v) => Some(*v as u32),
1321 Self::U16(v) => Some(*v as u32),
1322 Self::U32(v) => Some(*v),
1323 _ => None,
1324 }
1325 }
1326 };
1327 { $method:ident, u64 } => {
1328 pub fn $method(&self) -> Option<u64> {
1329 match self {
1330 Self::U8(v) => Some(*v as u64),
1331 Self::U16(v) => Some(*v as u64),
1332 Self::U32(v) => Some(*v as u64),
1333 Self::U64(v) => Some(*v),
1334 Self::C64(v) => Some(*v), // C64 is also u64
1335 _ => None,
1336 }
1337 }
1338 };
1339 { $method:ident, u128 } => {
1340 pub fn $method(&self) -> Option<u128> {
1341 match self {
1342 Self::U8(v) => Some(*v as u128),
1343 Self::U16(v) => Some(*v as u128),
1344 Self::U32(v) => Some(*v as u128),
1345 Self::U64(v) => Some(*v as u128),
1346 Self::C64(v) => Some(*v as u128),
1347 Self::U128(v) => Some(*v),
1348 _ => None,
1349 }
1350 }
1351 };
1352 // For signed integers - can convert from smaller signed types and smaller unsigned types
1353 { $method:ident, i8 } => {
1354 pub fn $method(&self) -> Option<i8> {
1355 match self {
1356 Self::I8(v) => Some(*v),
1357 _ => None,
1358 }
1359 }
1360 };
1361 { $method:ident, i16 } => {
1362 pub fn $method(&self) -> Option<i16> {
1363 match self {
1364 Self::U8(v) => Some(*v as i16),
1365 Self::I8(v) => Some(*v as i16),
1366 Self::I16(v) => Some(*v),
1367 _ => None,
1368 }
1369 }
1370 };
1371 { $method:ident, i32 } => {
1372 pub fn $method(&self) -> Option<i32> {
1373 match self {
1374 Self::U8(v) => Some(*v as i32),
1375 Self::U16(v) => Some(*v as i32),
1376 Self::I8(v) => Some(*v as i32),
1377 Self::I16(v) => Some(*v as i32),
1378 Self::I32(v) => Some(*v),
1379 _ => None,
1380 }
1381 }
1382 };
1383 { $method:ident, i64 } => {
1384 pub fn $method(&self) -> Option<i64> {
1385 match self {
1386 Self::U8(v) => Some(*v as i64),
1387 Self::U16(v) => Some(*v as i64),
1388 Self::U32(v) => Some(*v as i64),
1389 // Checked: a u64 above i64::MAX cannot be represented, and
1390 // None is honest where a wrapping cast would be a lie.
1391 Self::U64(v) => i64::try_from(*v).ok(),
1392 Self::C64(v) => i64::try_from(*v).ok(),
1393 Self::I8(v) => Some(*v as i64),
1394 Self::I16(v) => Some(*v as i64),
1395 Self::I32(v) => Some(*v as i64),
1396 Self::I64(v) => Some(*v),
1397 _ => None,
1398 }
1399 }
1400 };
1401 { $method:ident, i128 } => {
1402 pub fn $method(&self) -> Option<i128> {
1403 match self {
1404 Self::U8(v) => Some(*v as i128),
1405 Self::U16(v) => Some(*v as i128),
1406 Self::U32(v) => Some(*v as i128),
1407 Self::U64(v) => Some(*v as i128),
1408 Self::C64(v) => Some(*v as i128),
1409 Self::I8(v) => Some(*v as i128),
1410 Self::I16(v) => Some(*v as i128),
1411 Self::I32(v) => Some(*v as i128),
1412 Self::I64(v) => Some(*v as i128),
1413 Self::I128(v) => Some(*v),
1414 _ => None,
1415 }
1416 }
1417 };
1418
1419 { $method:ident, Float32 } => {
1420 pub fn $method(&self) -> Option<Float32> {
1421 match self {
1422 Self::U8(v) => Some(Float32(*v as f32)),
1423 Self::U16(v) => Some(Float32(*v as f32)),
1424 Self::U32(v) => Some(Float32(*v as f32)),
1425 Self::U64(v) => Some(Float32(*v as f32)),
1426 Self::U128(v) => Some(Float32(*v as f32)),
1427 Self::I8(v) => Some(Float32(*v as f32)),
1428 Self::I16(v) => Some(Float32(*v as f32)),
1429 Self::I32(v) => Some(Float32(*v as f32)),
1430 Self::I64(v) => Some(Float32(*v as f32)),
1431 Self::I128(v) => Some(Float32(*v as f32)),
1432 Self::F32(v) => Some(Float32(**v)),
1433 Self::F64(Float64(v)) => Some(Float32(*v as f32)),
1434 Self::Aint(bigint) => {
1435 // Convert BigInt to f32 (may lose precision for large values).
1436 use num_traits::ToPrimitive;
1437 bigint.to_f32().map(Float32)
1438 },
1439 Self::Adec(bigdec) => {
1440 // Through the decimal text, which the standard parser rounds correctly.
1441 // `BigDecimal::to_f32` scales by a power of ten in floating point and
1442 // rounds twice.
1443 bigdec.to_string().parse::<f32>().ok().map(Float32)
1444 },
1445 _ => None,
1446 }
1447 }
1448 };
1449 // For Float64 wrapper - convert from all numeric types
1450 { $method:ident, Float64 } => {
1451 pub fn $method(&self) -> Option<Float64> {
1452 match self {
1453 Self::U8(v) => Some(Float64(*v as f64)),
1454 Self::U16(v) => Some(Float64(*v as f64)),
1455 Self::U32(v) => Some(Float64(*v as f64)),
1456 Self::U64(v) => Some(Float64(*v as f64)),
1457 Self::U128(v) => Some(Float64(*v as f64)),
1458 Self::I8(v) => Some(Float64(*v as f64)),
1459 Self::I16(v) => Some(Float64(*v as f64)),
1460 Self::I32(v) => Some(Float64(*v as f64)),
1461 Self::I64(v) => Some(Float64(*v as f64)),
1462 Self::I128(v) => Some(Float64(*v as f64)),
1463 Self::F32(Float32(v)) => Some(Float64(*v as f64)),
1464 Self::F64(v) => Some(Float64(**v)),
1465 Self::Aint(bigint) => {
1466 // Convert BigInt to f64 (may lose precision for large values).
1467 use num_traits::ToPrimitive;
1468 bigint.to_f64().map(Float64)
1469 },
1470 Self::Adec(bigdec) => {
1471 // Through the decimal text, which the standard parser rounds correctly.
1472 // `BigDecimal::to_f64` scales by a power of ten in floating point and
1473 // rounds twice, so 0.3 came back as 0.30000000000000004.
1474 bigdec.to_string().parse::<f64>().ok().map(Float64)
1475 },
1476 _ => None,
1477 }
1478 }
1479 };
1480}
1481
1482#[macro_export]
1483/// For decoding homogenous byte tuples.
1484macro_rules! binary_decode_byte_tuple {
1485 { $variant:ident, $typ:ty, $n:literal, $buf:expr } => {
1486
1487 {
1488 const N: usize = $n;
1489 const L: usize = std::mem::size_of::<$typ>();
1490 if $buf.len() > N * L {
1491 let mut a: [$typ; N] = [0; N];
1492 let mut i: usize = 1;
1493 for j in 0..N {
1494 a[j] = <$typ>::from_be_bytes(
1495 res!(<[u8; L]>::try_from(&$buf[i..i+L]), Decode, Bytes)
1496 );
1497 i += L;
1498 }
1499 return Ok((Dat::$variant(a), i));
1500 } else {
1501 return Err(<Dat as FromBytes>::too_few(
1502 $buf.len(), N * L + 1, &Dat::code_name($buf[0]), file!(), line!()));
1503 }
1504 }
1505 };
1506 { $variant:ident, $wrap:ident, $typ:ty, $n:literal, $buf:expr } => {
1507
1508 {
1509 const N: usize = $n;
1510 const L: usize = std::mem::size_of::<$typ>();
1511 if $buf.len() > N * L {
1512 let mut a: [$typ; N] = [0; N];
1513 let mut i: usize = 1;
1514 for j in 0..N {
1515 a[j] = <$typ>::from_be_bytes(
1516 res!(<[u8; L]>::try_from(&$buf[i..i+L]), Decode, Bytes)
1517 );
1518 i += L;
1519 }
1520 return Ok((Dat::$variant($wrap(a)), i));
1521 } else {
1522 return Err(<Dat as FromBytes>::too_few(
1523 $buf.len(), N * L + 1, &Dat::code_name($buf[0]), file!(), line!()));
1524 }
1525 }
1526 };
1527}
1528
1529#[macro_export]
1530/// For reading homogenous byte tuples.
1531macro_rules! binary_read_byte_tuple {
1532 { $variant:ident, $typ:ty, $n:literal, $r:expr, $csum:expr } => {
1533
1534 {
1535 const N: usize = $n;
1536 const L: usize = std::mem::size_of::<$typ>();
1537 let mut a: [$typ; N] = [0; N];
1538 let mut i: usize = 1;
1539 for j in 0..N {
1540 let mut n = [0; L];
1541 res!($r.read_exact(&mut n));
1542 if let Some(csum) = $csum { res!(csum.update(&n)); }
1543 a[j] = <$typ>::from_be_bytes(
1544 res!(<[u8; L]>::try_from(&n[..]), Decode, Bytes)
1545 );
1546 i += L;
1547 }
1548 return Ok((Dat::$variant(a), i));
1549 }
1550
1551 };
1552 { $variant:ident, $wrap:ident, $typ:ty, $n:literal, $r:expr, $csum:expr } => {
1553
1554 {
1555 const N: usize = $n;
1556 const L: usize = std::mem::size_of::<$typ>();
1557 let mut a: [$typ; N] = [0; N];
1558 let mut i: usize = 1;
1559 for j in 0..N {
1560 let mut n = [0; L];
1561 res!($r.read_exact(&mut n));
1562 if let Some(csum) = $csum { res!(csum.update(&n)); }
1563 a[j] = <$typ>::from_be_bytes(
1564 res!(<[u8; L]>::try_from(&n[..]), Decode, Bytes)
1565 );
1566 i += L;
1567 }
1568 return Ok((Dat::$variant($wrap(a)), i));
1569 }
1570
1571 };
1572}
1573
1574#[macro_export]
1575/// For loading homogenous byte tuples.
1576macro_rules! binary_load_byte_tuple {
1577 { $variant:ident, $typ:ty, $n:literal, $r:expr, $byts:expr } => {
1578
1579 {
1580 const N: usize = $n;
1581 const L: usize = std::mem::size_of::<$typ>();
1582 for _ in 0..N {
1583 let mut a = [0; L];
1584 res!($r.read_exact(&mut a));
1585 $byts.extend_from_slice(&a[..]);
1586 }
1587 return Ok(())
1588 }
1589
1590 };
1591}
1592
1593#[macro_export]
1594/// For counting homogenous byte tuples.
1595macro_rules! binary_count_byte_tuple {
1596 { $typ:ty, $n:literal, $rs:expr, $count:expr } => {
1597
1598 {
1599 const N: usize = $n;
1600 const L: i64 = std::mem::size_of::<$typ>() as i64;
1601 for _ in 0..N {
1602 res!($rs.seek(SeekFrom::Current(L)));
1603 *$count += (L as usize);
1604 }
1605 return Ok(())
1606 }
1607
1608 };
1609}
1610
1611#[macro_export]
1612/// For unit testing of binary encoding and decoding for homogenous byte tuples.
1613macro_rules! test_binary_encode_decode_byte_tuple {
1614 { $arr:expr } => {
1615
1616 let d1 = Dat::from($arr);
1617 let mut buf = Vec::new();
1618 buf = res!(d1.to_bytes(buf));
1619 let (d2, n) = res!(Dat::from_bytes(&buf));
1620 req!(Some(n), d1.byte_len());
1621 req!(d1, d2);
1622
1623 };
1624}
1625
1626#[macro_export]
1627/// For string decoding an homogenous byte or integer tuple.
1628macro_rules! string_decode_heterogenous_tuple {
1629 { $target:ident, $len:literal, $list:expr, $state:expr } => {
1630
1631 return Ok(Dat::$target(Box::new(
1632 match $list.try_into() {
1633 Ok(a) => a,
1634 Err(_) => return Err(err!(
1635 "Length of {} string is {}.", $state.kind_outer, $len;
1636 Input, Invalid)),
1637 }
1638 )))
1639
1640 };
1641}
1642
1643#[macro_export]
1644/// For string decoding an homogenous byte or integer tuple.
1645macro_rules! string_decode_int_tuple {
1646 { $target:ident, $kind:ident, $typ:ty, $len:literal, $list:expr, $state:expr } => {
1647
1648 {
1649 if $list.len() != $len {
1650 return Err(err!(
1651 "Length of {} string is {}.", $state.kind_outer, $len;
1652 Input, Invalid));
1653 }
1654 let mut a: [$typ; $len] = [0; $len];
1655 let mut i: usize = 0;
1656 for d in $list {
1657 match d {
1658 Dat::$kind(n) => a[i] = n,
1659 _ => return Err(err!(
1660 "Expecting a daticle of kind {:?}, found {:?}.",
1661 Kind::$kind, d;
1662 Input, Mismatch, Unexpected, Bug)),
1663 }
1664 i += 1;
1665 }
1666 return Ok(Dat::$target(a));
1667 }
1668
1669 };
1670}
1671
1672#[macro_export]
1673/// For unit testing of string encoding and decoding of homogenous byte tuples.
1674macro_rules! test_string_encode_decode_homogenous_tuple {
1675 { $cfg:ident, $arr:expr } => {
1676
1677 let cfg_enc = EncoderConfig::<(), ()>::$cfg(None);
1678 let cfg_dec = DecoderConfig::<(), ()>::$cfg(None);
1679 let d1 = Dat::from($arr);
1680 let d1_str = res!(d1.encode_string_with_config(&cfg_enc));
1681 let d2 = res!(Dat::decode_string_with_config(d1_str, &cfg_dec));
1682 req!(d1, d2);
1683
1684 };
1685}
1686
1687#[cfg(test)]
1688mod tests {
1689 use crate::prelude::*;
1690 use oxedyne_fe2o3_core::prelude::*;
1691
1692 #[test]
1693 fn test_dat() {
1694 let v1 = dat!(42u8);
1695 assert_eq!(v1, Dat::from(42u8));
1696 }
1697
1698 #[test]
1699 fn test_listdat_01() {
1700 let v1 = listdat!["hello", "world", 42u8, listdat![ 1i16, 2i16, 256u16 ]];
1701 let v2 = Dat::List(vec![
1702 dat!("hello"),
1703 dat!("world"),
1704 dat!(42u8),
1705 Dat::List(vec![
1706 dat!(1i16),
1707 dat!(2i16),
1708 dat!(256u16),
1709 ]),
1710 ]);
1711 assert_eq!(v1, v2);
1712 }
1713
1714 #[test]
1715 fn test_listdat_02() {
1716 let v1 = listdat![1u16];
1717 let v2 = Dat::List(vec![dat!(1u16)]);
1718 assert_eq!(v1, v2);
1719 }
1720
1721 #[test]
1722 fn test_try_extract_dat_00() -> Outcome<()> {
1723 let n = 42u8;
1724 let d = dat!(n);
1725 let e = try_extract_dat!(d, U8);
1726 assert_eq!(n, e);
1727 Ok(())
1728 }
1729
1730 #[test]
1731 fn test_mapdat_01() -> Outcome<()> {
1732 let v1: Dat = mapdat!{
1733 listdat![1u16] => listdat![1u16, 2u16, 3u16],
1734 listdat![2u16] => listdat![1u16, 2u16, 3u16],
1735 };
1736 //assert_eq!(v1, v2);
1737 println!("map = {:?}",v1);
1738 Ok(())
1739 }
1740
1741 #[test]
1742 fn test_mapdat_02() -> Outcome<()> {
1743 let v1 = mapdat!{
1744 "Meaning of life" => 42u8,
1745 "key" => "value",
1746 "map" => mapdat!{
1747 1i16 => Dat::I32(2),
1748 3u8 => 4i8,
1749 },
1750 };
1751 let mut m1 = DaticleMap::new();
1752 m1.insert(dat!("Meaning of life"), dat!(42u8));
1753 m1.insert(dat!("key"), dat!("value"));
1754 let mut m2 = DaticleMap::new();
1755 m2.insert(dat!(1i16), dat!(2));
1756 m2.insert(dat!(3u8), dat!(4i8));
1757 m1.insert(dat!("map"), Dat::Map(m2));
1758 let v2 = Dat::Map(m1);
1759 assert_eq!(v1, v2);
1760 Ok(())
1761 }
1762}