1#[macro_export]
2macro_rules! if_all_true {
3 ( { } $( $fragment:item )* ) => { $( $fragment )* };
4 ( { false $($rest:tt)* } $( $fragment:item )* ) => { };
5 ( { true $($rest:tt)* } $( $fragment:item )* ) => { measures::if_all_true! { { $($rest)* } $( $fragment )* } };
6}
7
8#[macro_export]
9macro_rules! define_scalar_property {
10 ( $scalar_property:tt ) => {};
11}
12
13#[macro_export]
14macro_rules! define_vector_property {
15 ( $property_name:ident [ $( $unit:tt )* ]) => {};
17}
18
19#[macro_export]
20macro_rules! define_measure_types_aux {
21 {
23 ,
24
25 with_points: $with_points:tt,
26 with_directions: $with_directions:tt,
27 with_2d: $with_2d:tt,
28 with_3d: $with_3d:tt,
29 with_transformations: $with_transformations:tt,
30 exact: $exact:tt,
31 with_approx: $with_approx:tt,
32 with_correlation: $with_correlation:tt;
33
34 $(
35 scalar_properties [
36 $(
37 $scalar_prop:ident [
38 $(
39 $scalar_unit:ident {
40 $($scalar_key:ident : $scalar_val:expr),* $(,)?
41 }
42 )*
43 ]
44 )*
45 ]
46 )?
47
48 $(
49 vector_properties [
50 $(
51 $vector_prop:ident [
52 $(
53 $vector_unit:ident {
54 $($vector_key:ident : $vector_val:expr),* $(,)?
55 }
56 )*
57 ]
58 )*
59 ]
60 )?
61
62 $(
63 angle_measurement_units [
64 $(
65 $angle_unit:ident {
66 $($angle_key:ident : $angle_val:expr),* $(,)?
67 }
68 )*
69 ]
70 )?
71
72 $(
73 relationships [
74 $(
75 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
76 )*
77 ]
78 )?
79 } => {
80 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
81 use measures::{
82 dimensionless::{Dimensionless, One},
83 angle::{Angle, Radian},
84 traits::{
85 AngleMeasurementUnit, ArithmeticOps, LossyFrom, MeasurementUnit, Sqrt, VectorProperty, Trigonometry,
86 },
87 };
88 use core::fmt;
89 use core::marker::PhantomData;
90
91 measures::inner_define_measure! { $with_approx }
92 measures::if_all_true! { { $with_approx }
93 measures::inner_define_approx_measure! { $exact }
94 }
95 measures::if_all_true! { { $with_points }
96 measures::inner_define_measure_point! { $with_approx }
97 }
98 measures::if_all_true! { { $with_approx $with_points }
99 measures::inner_define_approx_measure_point ! { $exact }
100 }
101 measures::if_all_true! { { $exact $with_directions }
102 measures::inner_define_unsigned_direction! { $with_points }
103 }
104 measures::if_all_true! { { $exact $with_directions }
105 measures::inner_define_signed_direction! { $with_points }
106 }
107 measures::if_all_true! { { $with_2d }
108 measures::inner_define_measure_2d! { $with_points $with_directions $with_approx }
109 }
110 measures::if_all_true! { { $with_2d $with_points $exact }
111 measures::inner_define_measure_point_2d! { $with_approx }
112 }
113 measures::if_all_true! { { $with_3d }
114 measures::inner_define_measure_3d! { $with_approx }
115 }
116 measures::if_all_true! { { $with_points $with_3d }
117 measures::inner_define_measure_point_3d! { $with_approx }
118 }
119 measures::if_all_true! { { $with_2d $with_transformations }
120 measures::inner_define_linear_map_2d! {}
121 }
122 measures::if_all_true! { { $with_3d $with_transformations }
123 measures::inner_define_linear_map_3d! {}
124 }
125 measures::if_all_true! { { $with_2d $with_transformations $with_points }
126 measures::inner_define_affine_map_2d! {}
127 }
128 measures::if_all_true! { { $with_3d $with_transformations $with_points }
129 measures::inner_define_affine_map_3d! {}
130 }
131
132 measures::if_all_true! { { $with_approx $with_2d }
133 measures::inner_define_approx_measure_2d! { $exact }
134 }
135 measures::if_all_true! { { $with_approx $with_points $with_2d }
136 measures::inner_define_approx_measure_point_2d! { $exact }
137 }
138 measures::if_all_true! { { $with_approx $with_3d }
139 measures::inner_define_approx_measure_3d! { $exact }
140 }
141 measures::if_all_true! { { $with_approx $with_points $with_3d }
142 measures::inner_define_approx_measure_point_3d! { $exact }
143 }
144
145 $(
147 $(
148 measures::measurement_scalar_property! { $scalar_prop }
149 $(
150 measures::measurement_unit! {
151 name: $scalar_unit,
152 property: $scalar_prop,
153 $(
154 $scalar_key: $scalar_val,
155 )*
156 with_2d: $with_2d,
157 with_3d: $with_3d,
158 vector: false,
159 }
160 )*
161 )*
162 )?
163
164 $(
166 $(
167 measures::measurement_vector_property! { $vector_prop }
168 $(
169 measures::measurement_unit! {
170 name: $vector_unit,
171 property: $vector_prop,
172 $(
173 $vector_key: $vector_val,
174 )*
175 with_2d: $with_2d,
176 with_3d: $with_3d,
177 vector: true,
178 }
179 )*
180 )*
181 )?
182
183 $(
185 $(
186 measures::angle_measurement_unit! {
187 name: $angle_unit,
188 $(
189 $angle_key: $angle_val,
190 )*
191 }
192 )*
193 )?
194
195 $(
197 $(
198 measures::define_units_relationship! {
199 $exact $with_approx $with_correlation,
200 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
201 }
202 )*
203 )?
204 };
205
206 {
208 with_points $( $flag:ident )*,
209
210 with_points: false,
211 with_directions: $with_directions:tt,
212 with_2d: $with_2d:tt,
213 with_3d: $with_3d:tt,
214 with_transformations: $with_transformations:tt,
215 exact: $exact:tt,
216 with_approx: $with_approx:tt,
217 with_correlation: $with_correlation:tt;
218
219 $(
220 scalar_properties [
221 $(
222 $scalar_prop:ident [
223 $(
224 $scalar_unit:ident {
225 $($scalar_key:ident : $scalar_val:expr),* $(,)?
226 }
227 )*
228 ]
229 )*
230 ]
231 )?
232
233 $(
234 vector_properties [
235 $(
236 $vector_prop:ident [
237 $(
238 $vector_unit:ident {
239 $($vector_key:ident : $vector_val:expr),* $(,)?
240 }
241 )*
242 ]
243 )*
244 ]
245 )?
246
247 $(
248 angle_measurement_units [
249 $(
250 $angle_unit:ident {
251 $($angle_key:ident : $angle_val:expr),* $(,)?
252 }
253 )*
254 ]
255 )?
256
257 $(
258 relationships [
259 $(
260 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
261 )*
262 ]
263 )?
264 } => {
265 measures::define_measure_types_aux!{
266 $( $flag ) *,
267
268 with_points: true,
269 with_directions: $with_directions,
270 with_2d: $with_2d,
271 with_3d: $with_3d,
272 with_transformations: $with_transformations,
273 exact: $exact,
274 with_approx: $with_approx,
275 with_correlation: $with_correlation;
276
277 $(
278 scalar_properties [
279 $(
280 $scalar_prop [
281 $(
282 $scalar_unit {
283 $($scalar_key : $scalar_val),*
284 }
285 )*
286 ]
287 )*
288 ]
289 )?
290
291 $(
292 vector_properties [
293 $(
294 $vector_prop [
295 $(
296 $vector_unit {
297 $($vector_key : $vector_val),*
298 }
299 )*
300 ]
301 )*
302 ]
303 )?
304
305 $(
306 angle_measurement_units [
307 $(
308 $angle_unit {
309 $($angle_key : $angle_val),*
310 }
311 )*
312 ]
313 )?
314
315 $(
316 relationships [
317 $(
318 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
319 )*
320 ]
321 )?
322 }
323 };
324
325 {
327 with_directions $( $flag:ident )*,
328
329 with_points: $with_points:tt,
330 with_directions: false,
331 with_2d: $with_2d:tt,
332 with_3d: $with_3d:tt,
333 with_transformations: $with_transformations:tt,
334 exact: $exact:tt,
335 with_approx: $with_approx:tt,
336 with_correlation: $with_correlation:tt;
337
338 $(
339 scalar_properties [
340 $(
341 $scalar_prop:ident [
342 $(
343 $scalar_unit:ident {
344 $($scalar_key:ident : $scalar_val:expr),* $(,)?
345 }
346 )*
347 ]
348 )*
349 ]
350 )?
351
352 $(
353 vector_properties [
354 $(
355 $vector_prop:ident [
356 $(
357 $vector_unit:ident {
358 $($vector_key:ident : $vector_val:expr),* $(,)?
359 }
360 )*
361 ]
362 )*
363 ]
364 )?
365
366 $(
367 angle_measurement_units [
368 $(
369 $angle_unit:ident {
370 $($angle_key:ident : $angle_val:expr),* $(,)?
371 }
372 )*
373 ]
374 )?
375
376 $(
377 relationships [
378 $(
379 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
380 )*
381 ]
382 )?
383 } => {
384 measures::define_measure_types_aux!{
385 $( $flag ) *,
386
387 with_points: $with_points,
388 with_directions: true,
389 with_2d: $with_2d,
390 with_3d: $with_3d,
391 with_transformations: $with_transformations,
392 exact: $exact,
393 with_approx: $with_approx,
394 with_correlation: $with_correlation;
395
396 $(
397 scalar_properties [
398 $(
399 $scalar_prop [
400 $(
401 $scalar_unit {
402 $($scalar_key : $scalar_val),*
403 }
404 )*
405 ]
406 )*
407 ]
408 )?
409
410 $(
411 vector_properties [
412 $(
413 $vector_prop [
414 $(
415 $vector_unit {
416 $($vector_key : $vector_val),*
417 }
418 )*
419 ]
420 )*
421 ]
422 )?
423
424 $(
425 angle_measurement_units [
426 $(
427 $angle_unit {
428 $($angle_key : $angle_val),*
429 }
430 )*
431 ]
432 )?
433
434 $(
435 relationships [
436 $(
437 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
438 )*
439 ]
440 )?
441 }
442 };
443
444 {
446 with_2d $( $flag:ident )*,
447
448 with_points: $with_points:tt,
449 with_directions: $with_directions:tt,
450 with_2d: false,
451 with_3d: $with_3d:tt,
452 with_transformations: $with_transformations:tt,
453 exact: $exact:tt,
454 with_approx: $with_approx:tt,
455 with_correlation: $with_correlation:tt;
456
457 $(
458 scalar_properties [
459 $(
460 $scalar_prop:ident [
461 $(
462 $scalar_unit:ident {
463 $($scalar_key:ident : $scalar_val:expr),* $(,)?
464 }
465 )*
466 ]
467 )*
468 ]
469 )?
470
471 $(
472 vector_properties [
473 $(
474 $vector_prop:ident [
475 $(
476 $vector_unit:ident {
477 $($vector_key:ident : $vector_val:expr),* $(,)?
478 }
479 )*
480 ]
481 )*
482 ]
483 )?
484
485 $(
486 angle_measurement_units [
487 $(
488 $angle_unit:ident {
489 $($angle_key:ident : $angle_val:expr),* $(,)?
490 }
491 )*
492 ]
493 )?
494
495 $(
496 relationships [
497 $(
498 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
499 )*
500 ]
501 )?
502 } => {
503 measures::define_measure_types_aux!{
504 $( $flag ) *,
505
506 with_points: $with_points,
507 with_directions: $with_directions,
508 with_2d: true,
509 with_3d: $with_3d,
510 with_transformations: $with_transformations,
511 exact: $exact,
512 with_approx: $with_approx,
513 with_correlation: $with_correlation;
514
515 $(
516 scalar_properties [
517 $(
518 $scalar_prop [
519 $(
520 $scalar_unit {
521 $($scalar_key : $scalar_val),*
522 }
523 )*
524 ]
525 )*
526 ]
527 )?
528
529 $(
530 vector_properties [
531 $(
532 $vector_prop [
533 $(
534 $vector_unit {
535 $($vector_key : $vector_val),*
536 }
537 )*
538 ]
539 )*
540 ]
541 )?
542
543 $(
544 angle_measurement_units [
545 $(
546 $angle_unit {
547 $($angle_key : $angle_val),*
548 }
549 )*
550 ]
551 )?
552
553 $(
554 relationships [
555 $(
556 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
557 )*
558 ]
559 )?
560 }
561 };
562
563 {
565 with_3d $( $flag:ident )*,
566
567 with_points: $with_points:tt,
568 with_directions: $with_directions:tt,
569 with_2d: $with_2d:tt,
570 with_3d: false,
571 with_transformations: $with_transformations:tt,
572 exact: $exact:tt,
573 with_approx: $with_approx:tt,
574 with_correlation: $with_correlation:tt;
575
576 $(
577 scalar_properties [
578 $(
579 $scalar_prop:ident [
580 $(
581 $scalar_unit:ident {
582 $($scalar_key:ident : $scalar_val:expr),* $(,)?
583 }
584 )*
585 ]
586 )*
587 ]
588 )?
589
590 $(
591 vector_properties [
592 $(
593 $vector_prop:ident [
594 $(
595 $vector_unit:ident {
596 $($vector_key:ident : $vector_val:expr),* $(,)?
597 }
598 )*
599 ]
600 )*
601 ]
602 )?
603
604 $(
605 angle_measurement_units [
606 $(
607 $angle_unit:ident {
608 $($angle_key:ident : $angle_val:expr),* $(,)?
609 }
610 )*
611 ]
612 )?
613
614 $(
615 relationships [
616 $(
617 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
618 )*
619 ]
620 )?
621 } => {
622 measures::define_measure_types_aux!{
623 $( $flag ) *,
624
625 with_points: $with_points,
626 with_directions: $with_directions,
627 with_2d: $with_2d,
628 with_3d: true,
629 with_transformations: $with_transformations,
630 exact: $exact,
631 with_approx: $with_approx,
632 with_correlation: $with_correlation;
633
634 $(
635 scalar_properties [
636 $(
637 $scalar_prop [
638 $(
639 $scalar_unit {
640 $($scalar_key : $scalar_val),*
641 }
642 )*
643 ]
644 )*
645 ]
646 )?
647
648 $(
649 vector_properties [
650 $(
651 $vector_prop [
652 $(
653 $vector_unit {
654 $($vector_key : $vector_val),*
655 }
656 )*
657 ]
658 )*
659 ]
660 )?
661
662 $(
663 angle_measurement_units [
664 $(
665 $angle_unit {
666 $($angle_key : $angle_val),*
667 }
668 )*
669 ]
670 )?
671
672 $(
673 relationships [
674 $(
675 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
676 )*
677 ]
678 )?
679 }
680 };
681
682 {
684 with_transformations $( $flag:ident )*,
685
686 with_points: $with_points:tt,
687 with_directions: $with_directions:tt,
688 with_2d: $with_2d:tt,
689 with_3d: $with_3d:tt,
690 with_transformations: false,
691 exact: $exact:tt,
692 with_approx: $with_approx:tt,
693 with_correlation: $with_correlation:tt;
694
695 $(
696 scalar_properties [
697 $(
698 $scalar_prop:ident [
699 $(
700 $scalar_unit:ident {
701 $($scalar_key:ident : $scalar_val:expr),* $(,)?
702 }
703 )*
704 ]
705 )*
706 ]
707 )?
708
709 $(
710 vector_properties [
711 $(
712 $vector_prop:ident [
713 $(
714 $vector_unit:ident {
715 $($vector_key:ident : $vector_val:expr),* $(,)?
716 }
717 )*
718 ]
719 )*
720 ]
721 )?
722
723 $(
724 angle_measurement_units [
725 $(
726 $angle_unit:ident {
727 $($angle_key:ident : $angle_val:expr),* $(,)?
728 }
729 )*
730 ]
731 )?
732
733 $(
734 relationships [
735 $(
736 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
737 )*
738 ]
739 )?
740 } => {
741 measures::define_measure_types_aux!{
742 $( $flag ) *,
743
744 with_points: $with_points,
745 with_directions: $with_directions,
746 with_2d: $with_2d,
747 with_3d: $with_3d,
748 with_transformations: true,
749 exact: $exact,
750 with_approx: $with_approx,
751 with_correlation: $with_correlation;
752
753 $(
754 scalar_properties [
755 $(
756 $scalar_prop [
757 $(
758 $scalar_unit {
759 $($scalar_key : $scalar_val),*
760 }
761 )*
762 ]
763 )*
764 ]
765 )?
766
767 $(
768 vector_properties [
769 $(
770 $vector_prop [
771 $(
772 $vector_unit {
773 $($vector_key : $vector_val),*
774 }
775 )*
776 ]
777 )*
778 ]
779 )?
780
781 $(
782 angle_measurement_units [
783 $(
784 $angle_unit {
785 $($angle_key : $angle_val),*
786 }
787 )*
788 ]
789 )?
790
791 $(
792 relationships [
793 $(
794 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
795 )*
796 ]
797 )?
798 }
799 };
800
801 {
803 exact $( $flag:ident )*,
804
805 with_points: $with_points:tt,
806 with_directions: $with_directions:tt,
807 with_2d: $with_2d:tt,
808 with_3d: $with_3d:tt,
809 with_transformations: $with_transformations:tt,
810 exact: false,
811 with_approx: $with_approx:tt,
812 with_correlation: $with_correlation:tt;
813
814 $(
815 scalar_properties [
816 $(
817 $scalar_prop:ident [
818 $(
819 $scalar_unit:ident {
820 $($scalar_key:ident : $scalar_val:expr),* $(,)?
821 }
822 )*
823 ]
824 )*
825 ]
826 )?
827
828 $(
829 vector_properties [
830 $(
831 $vector_prop:ident [
832 $(
833 $vector_unit:ident {
834 $($vector_key:ident : $vector_val:expr),* $(,)?
835 }
836 )*
837 ]
838 )*
839 ]
840 )?
841
842 $(
843 angle_measurement_units [
844 $(
845 $angle_unit:ident {
846 $($angle_key:ident : $angle_val:expr),* $(,)?
847 }
848 )*
849 ]
850 )?
851
852 $(
853 relationships [
854 $(
855 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
856 )*
857 ]
858 )?
859 } => {
860 measures::define_measure_types_aux!{
861 $( $flag ) *,
862
863 with_points: $with_points,
864 with_directions: $with_directions,
865 with_2d: $with_2d,
866 with_3d: $with_3d,
867 with_transformations: $with_transformations,
868 exact: true,
869 with_approx: $with_approx,
870 with_correlation: $with_correlation;
871
872 $(
873 scalar_properties [
874 $(
875 $scalar_prop [
876 $(
877 $scalar_unit {
878 $($scalar_key : $scalar_val),*
879 }
880 )*
881 ]
882 )*
883 ]
884 )?
885
886 $(
887 vector_properties [
888 $(
889 $vector_prop [
890 $(
891 $vector_unit {
892 $($vector_key : $vector_val),*
893 }
894 )*
895 ]
896 )*
897 ]
898 )?
899
900 $(
901 angle_measurement_units [
902 $(
903 $angle_unit {
904 $($angle_key : $angle_val),*
905 }
906 )*
907 ]
908 )?
909
910 $(
911 relationships [
912 $(
913 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
914 )*
915 ]
916 )?
917 }
918 };
919
920 {
922 with_approx $( $flag:ident )*,
923
924 with_points: $with_points:tt,
925 with_directions: $with_directions:tt,
926 with_2d: $with_2d:tt,
927 with_3d: $with_3d:tt,
928 with_transformations: $with_transformations:tt,
929 exact: $exact:tt,
930 with_approx: false,
931 with_correlation: $with_correlation:tt;
932
933 $(
934 scalar_properties [
935 $(
936 $scalar_prop:ident [
937 $(
938 $scalar_unit:ident {
939 $($scalar_key:ident : $scalar_val:expr),* $(,)?
940 }
941 )*
942 ]
943 )*
944 ]
945 )?
946
947 $(
948 vector_properties [
949 $(
950 $vector_prop:ident [
951 $(
952 $vector_unit:ident {
953 $($vector_key:ident : $vector_val:expr),* $(,)?
954 }
955 )*
956 ]
957 )*
958 ]
959 )?
960
961 $(
962 angle_measurement_units [
963 $(
964 $angle_unit:ident {
965 $($angle_key:ident : $angle_val:expr),* $(,)?
966 }
967 )*
968 ]
969 )?
970
971 $(
972 relationships [
973 $(
974 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
975 )*
976 ]
977 )?
978 } => {
979 measures::define_measure_types_aux!{
980 $( $flag ) *,
981
982 with_points: $with_points,
983 with_directions: $with_directions,
984 with_2d: $with_2d,
985 with_3d: $with_3d,
986 with_transformations: $with_transformations,
987 exact: $exact,
988 with_approx: true,
989 with_correlation: $with_correlation;
990
991 $(
992 scalar_properties [
993 $(
994 $scalar_prop [
995 $(
996 $scalar_unit {
997 $($scalar_key : $scalar_val),*
998 }
999 )*
1000 ]
1001 )*
1002 ]
1003 )?
1004
1005 $(
1006 vector_properties [
1007 $(
1008 $vector_prop [
1009 $(
1010 $vector_unit {
1011 $($vector_key : $vector_val),*
1012 }
1013 )*
1014 ]
1015 )*
1016 ]
1017 )?
1018
1019 $(
1020 angle_measurement_units [
1021 $(
1022 $angle_unit {
1023 $($angle_key : $angle_val),*
1024 }
1025 )*
1026 ]
1027 )?
1028
1029 $(
1030 relationships [
1031 $(
1032 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
1033 )*
1034 ]
1035 )?
1036 }
1037 };
1038
1039 {
1041 with_correlation $( $flag:ident )*,
1042
1043 with_points: $with_points:tt,
1044 with_directions: $with_directions:tt,
1045 with_2d: $with_2d:tt,
1046 with_3d: $with_3d:tt,
1047 with_transformations: $with_transformations:tt,
1048 exact: $exact:tt,
1049 with_approx: $with_approx:tt,
1050 with_correlation: false;
1051
1052 $(
1053 scalar_properties [
1054 $(
1055 $scalar_prop:ident [
1056 $(
1057 $scalar_unit:ident {
1058 $($scalar_key:ident : $scalar_val:expr),* $(,)?
1059 }
1060 )*
1061 ]
1062 )*
1063 ]
1064 )?
1065
1066 $(
1067 vector_properties [
1068 $(
1069 $vector_prop:ident [
1070 $(
1071 $vector_unit:ident {
1072 $($vector_key:ident : $vector_val:expr),* $(,)?
1073 }
1074 )*
1075 ]
1076 )*
1077 ]
1078 )?
1079
1080 $(
1081 angle_measurement_units [
1082 $(
1083 $angle_unit:ident {
1084 $($angle_key:ident : $angle_val:expr),* $(,)?
1085 }
1086 )*
1087 ]
1088 )?
1089
1090 $(
1091 relationships [
1092 $(
1093 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
1094 )*
1095 ]
1096 )?
1097 } => {
1098 measures::define_measure_types_aux!{
1099 $( $flag ) *,
1100 with_points: $with_points,
1101 with_directions: $with_directions,
1102 with_2d: $with_2d,
1103 with_3d: $with_3d,
1104 with_transformations: $with_transformations,
1105 exact: $exact,
1106 with_approx: $with_approx,
1107 with_correlation: true;
1108
1109 $(
1110 scalar_properties [
1111 $(
1112 $scalar_prop [
1113 $(
1114 $scalar_unit {
1115 $($scalar_key : $scalar_val),*
1116 }
1117 )*
1118 ]
1119 )*
1120 ]
1121 )?
1122
1123 $(
1124 vector_properties [
1125 $(
1126 $vector_prop [
1127 $(
1128 $vector_unit {
1129 $($vector_key : $vector_val),*
1130 }
1131 )*
1132 ]
1133 )*
1134 ]
1135 )?
1136
1137 $(
1138 angle_measurement_units [
1139 $(
1140 $angle_unit {
1141 $($angle_key : $angle_val),*
1142 }
1143 )*
1144 ]
1145 )?
1146
1147 $(
1148 relationships [
1149 $(
1150 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
1151 )*
1152 ]
1153 )?
1154 }
1155 };
1156}
1157
1158#[macro_export]
1159macro_rules! define_measure_types {
1160 (
1161 $( $flag:ident )* ,
1162
1163 $(
1164 scalar_properties [
1165 $(
1166 $scalar_prop:ident [
1167 $(
1168 $scalar_unit:ident {
1169 $($scalar_key:ident : $scalar_val:expr),* $(,)?
1170 }
1171 )*
1172 ]
1173 )*
1174 ]
1175 )?
1176
1177 $(
1178 vector_properties [
1179 $(
1180 $vector_prop:ident [
1181 $(
1182 $vector_unit:ident {
1183 $($vector_key:ident : $vector_val:expr),* $(,)?
1184 }
1185 )*
1186 ]
1187 )*
1188 ]
1189 )?
1190
1191 $(
1192 angle_measurement_units [
1193 $(
1194 $angle_unit:ident {
1195 $($angle_key:ident : $angle_val:expr),* $(,)?
1196 }
1197 )*
1198 ]
1199 )?
1200
1201 $(
1202 relationships [
1203 $(
1204 $unit1:ident $dim1:tt == $unit2:ident $dim2:tt $op:tt $unit3:ident $dim3:tt $(,)?
1205 )*
1206 ]
1207 )?
1208 ) => {
1209 measures::define_measure_types_aux! {
1210 $( $flag )* ,
1211
1212 with_points: false,
1213 with_directions: false,
1214 with_2d: false,
1215 with_3d: false,
1216 with_transformations: false,
1217 exact: false,
1218 with_approx: false,
1219 with_correlation: false;
1220
1221 $(
1222 scalar_properties [
1223 $(
1224 $scalar_prop [
1225 $(
1226 $scalar_unit {
1227 $($scalar_key : $scalar_val),*
1228 }
1229 )*
1230 ]
1231 )*
1232 ]
1233 )?
1234
1235 $(
1236 vector_properties [
1237 $(
1238 $vector_prop [
1239 $(
1240 $vector_unit {
1241 $($vector_key : $vector_val),*
1242 }
1243 )*
1244 ]
1245 )*
1246 ]
1247 )?
1248
1249 $(
1250 angle_measurement_units [
1251 $(
1252 $angle_unit {
1253 $($angle_key : $angle_val),*
1254 }
1255 )*
1256 ]
1257 )?
1258
1259 $(
1260 relationships [
1261 $(
1262 $unit1 $dim1 == $unit2 $dim2 $op $unit3 $dim3
1263 )*
1264 ]
1265 )?
1266 }
1267 };
1268}
1269
1270#[macro_export]
1271macro_rules! measurement_scalar_property {
1272 ($name:ident) => {
1273 pub struct $name;
1275 impl $crate::traits::MeasurementProperty for $name {}
1276 impl $crate::traits::ScalarProperty for $name {}
1277 };
1278}
1279
1280#[macro_export]
1281macro_rules! measurement_vector_property {
1282 ($name:ident) => {
1283 pub struct $name;
1285 impl $crate::traits::MeasurementProperty for $name {}
1286 impl $crate::traits::VectorProperty for $name {}
1287 };
1288}
1289
1290#[macro_export]
1291macro_rules! angle_measurement_unit {
1292 {
1293 name: $name:ident,
1294 suffix: $suffix:expr,
1295 cycle_fraction: $cycle_fraction:expr,
1296 } => {
1297 $crate::angle_measurement_unit! {
1298 name: $name,
1299 suffix: $suffix,
1300 offset: 0.,
1301 cycle_fraction: $cycle_fraction,
1302 }
1303 };
1304 {
1305 name: $name:ident,
1306 suffix: $suffix:expr,
1307 offset: $offset:expr,
1308 cycle_fraction: $cycle_fraction:expr,
1309 } => {
1310 pub struct $name;
1312 impl measures::traits::MeasurementUnit for $name {
1313 type Property = $crate::angle::Angle;
1314 const RATIO: f64 = core::f64::consts::TAU / ($cycle_fraction);
1315 const OFFSET: f64 = $offset;
1316 const SUFFIX: &'static str = $suffix;
1317 }
1318
1319 impl measures::traits::AngleMeasurementUnit for $name {
1320 const CYCLE_FRACTION: f64 = $cycle_fraction;
1321 }
1322
1323 impl<Number> core::ops::Mul<Measure<$name, Number>> for Measure<measures::dimensionless::One, Number>
1324 where
1325 Number: measures::traits::ArithmeticOps,
1326 {
1327 type Output = Measure<$name, Number>;
1328
1329 fn mul(self, other: Measure<$name, Number>) -> Measure<$name, Number> {
1331 Measure::<$name, Number>::new(self.value * other.value)
1332 }
1333 }
1334
1335 impl<Number> core::ops::Div<Measure<measures::dimensionless::One, Number>> for Measure<$name, Number>
1336 where
1337 Number: measures::traits::ArithmeticOps,
1338 {
1339 type Output = Self;
1340
1341 fn div(self, other: Measure<measures::dimensionless::One, Number>) -> Self::Output {
1343 Self::new(self.value / other.value)
1344 }
1345 }
1346 };
1347}
1348
1349#[macro_export]
1350macro_rules! measurement_unit_aux {
1351 {
1352 name: $name:ident,
1353 property: $property:ident,
1354 suffix: $suffix:expr,
1355 ratio: $ratio:expr,
1356 offset: $offset:expr,
1357 with_2d: $with_2d:tt,
1358 with_3d: $with_3d:tt,
1359 vector: $vector:tt,
1360 } => {
1361 pub struct $name;
1363 impl measures::traits::MeasurementUnit for $name {
1364 type Property = $property;
1365 const RATIO: f64 = $ratio;
1366 const OFFSET: f64 = $offset;
1367 const SUFFIX: &'static str = $suffix;
1368 }
1369
1370 impl<Number> core::ops::Mul<Measure<$name, Number>> for Measure<measures::dimensionless::One, Number>
1371 where
1372 Number: measures::traits::ArithmeticOps,
1373 {
1374 type Output = Measure<$name, Number>;
1375
1376 fn mul(self, other: Measure<$name, Number>) -> Measure<$name, Number> {
1378 Measure::<$name, Number>::new(self.value * other.value)
1379 }
1380 }
1381
1382 impl<Number> core::ops::Div<Measure<measures::dimensionless::One, Number>> for Measure<$name, Number>
1383 where
1384 Number: measures::traits::ArithmeticOps,
1385 {
1386 type Output = Self;
1387
1388 fn div(self, other: Measure<measures::dimensionless::One, Number>) -> Self::Output {
1390 Self::new(self.value / other.value)
1391 }
1392 }
1393
1394 measures::if_all_true! { { $with_2d $vector }
1395 impl<Number> core::ops::Mul<Measure<$name, Number>> for Measure2d<measures::dimensionless::One, Number>
1396 where
1397 Number: measures::traits::ArithmeticOps,
1398 {
1399 type Output = Measure2d<$name, Number>;
1400
1401 fn mul(self, other: Measure<$name, Number>) -> Self::Output {
1403 Measure2d::<$name, Number>::new([
1404 self.values[0] * other.value,
1405 self.values[1] * other.value,
1406 ])
1407 }
1408 }
1409
1410 impl<Number> core::ops::Mul<Measure2d<One, Number>> for Measure<$name, Number>
1411 where
1412 Number: measures::traits::ArithmeticOps,
1413 {
1414 type Output = Measure2d<$name, Number>;
1415
1416 fn mul(self, other: Measure2d<One, Number>) -> Self::Output {
1418 Measure2d::<$name, Number>::new([
1419 self.value * other.values[0],
1420 self.value * other.values[1],
1421 ])
1422 }
1423 }
1424
1425 impl<Number> core::ops::Div<Measure<measures::dimensionless::One, Number>> for Measure2d<$name, Number>
1426 where
1427 Number: measures::traits::ArithmeticOps,
1428 {
1429 type Output = Self;
1430
1431 fn div(self, other: Measure<measures::dimensionless::One, Number>) -> Self::Output {
1433 Self::new([
1434 self.values[0] / other.value,
1435 self.values[1] / other.value,
1436 ])
1437 }
1438 }
1439 }
1440
1441 measures::if_all_true! { { $with_3d $vector }
1442 impl<Number> core::ops::Mul<Measure<$name, Number>> for Measure3d<measures::dimensionless::One, Number>
1443 where
1444 Number: measures::traits::ArithmeticOps,
1445 {
1446 type Output = Measure3d<$name, Number>;
1447
1448 fn mul(self, other: Measure<$name, Number>) -> Self::Output {
1450 Measure3d::<$name, Number>::new([
1451 self.values[0] * other.value,
1452 self.values[1] * other.value,
1453 self.values[2] * other.value,
1454 ])
1455 }
1456 }
1457
1458 impl<Number> core::ops::Mul<Measure3d<One, Number>> for Measure<$name, Number>
1459 where
1460 Number: measures::traits::ArithmeticOps,
1461 {
1462 type Output = Measure3d<$name, Number>;
1463
1464 fn mul(self, other: Measure3d<One, Number>) -> Self::Output {
1466 Measure3d::<$name, Number>::new([
1467 self.value * other.values[0],
1468 self.value * other.values[1],
1469 self.value * other.values[2],
1470 ])
1471 }
1472 }
1473
1474 impl<Number> core::ops::Div<Measure<measures::dimensionless::One, Number>> for Measure3d<$name, Number>
1475 where
1476 Number: measures::traits::ArithmeticOps,
1477 {
1478 type Output = Self;
1479
1480 fn div(self, other: Measure<measures::dimensionless::One, Number>) -> Self::Output {
1482 Self::new([
1483 self.values[0] / other.value,
1484 self.values[1] / other.value,
1485 self.values[2] / other.value,
1486 ])
1487 }
1488 }
1489 }
1490 };
1491}
1492
1493#[macro_export]
1494macro_rules! measurement_unit {
1495 {
1496 name: $name:ident,
1497 property: $property:ident,
1498 suffix: $suffix:expr,
1499 with_2d: $with_2d:tt,
1500 with_3d: $with_3d:tt,
1501 vector: $vector:tt,
1502 } => {
1503 $crate::measurement_unit! {
1504 name: $name,
1505 property: $property,
1506 suffix: $suffix,
1507 ratio: 1.,
1508 with_2d: $with_2d,
1509 with_3d: $with_3d,
1510 vector: $vector,
1511 }
1512 };
1513 {
1514 name: $name:ident,
1515 property: $property:ident,
1516 suffix: $suffix:expr,
1517 ratio: $ratio:expr,
1518 with_2d: $with_2d:tt,
1519 with_3d: $with_3d:tt,
1520 vector: true,
1521 } => {
1522 $crate::measurement_unit_aux! {
1523 name: $name,
1524 property: $property,
1525 suffix: $suffix,
1526 ratio: $ratio,
1527 offset: 0.,
1528 with_2d: $with_2d,
1529 with_3d: $with_3d,
1530 vector: true,
1531 }
1532 };
1533 {
1534 name: $name:ident,
1535 property: $property:ident,
1536 suffix: $suffix:expr,
1537 ratio: $ratio:expr,
1538 with_2d: $with_2d:tt,
1539 with_3d: $with_3d:tt,
1540 vector: false,
1541 } => {
1542 $crate::measurement_unit_aux! {
1543 name: $name,
1544 property: $property,
1545 suffix: $suffix,
1546 ratio: $ratio,
1547 offset: 0.,
1548 with_2d: $with_2d,
1549 with_3d: $with_3d,
1550 vector: false,
1551 }
1552 };
1553 {
1554 name: $name:ident,
1555 property: $property:ident,
1556 suffix: $suffix:expr,
1557 ratio: $ratio:expr,
1558 offset: $offset:expr,
1559 with_2d: $with_2d:tt,
1560 with_3d: $with_3d:tt,
1561 vector: false,
1562 } => {
1563 $crate::measurement_unit_aux! {
1564 name: $name,
1565 property: $property,
1566 suffix: $suffix,
1567 ratio: $ratio,
1568 offset: $offset,
1569 with_2d: $with_2d,
1570 with_3d: $with_3d,
1571 vector: false,
1572 }
1573 };
1574}