nsw_types/
trait_impls.rs

1use crate::*;
2
3// This macro expands to all combinations of pairs in the two given sets, for example:
4// all_combos!({1, 2}, {a, b}) -> [(1, a), (1, b), (2, a), (2, b)]
5// Braces are used to denote arrays because square brackets around a type (e.g. [u16]) get parsed as
6// part of the type
7// For each combination, the given macro is called.
8macro_rules! all_combos {
9    // The final match: all_combos!(lh, rh, @macro)
10    ($lh:ty, $rh:ty, @$macro:ident) => {
11        $macro!($lh, $rh);
12    };
13    // Matches a plain lh and a single, wrapped rh: all_combos!(lh, {rh}, @macro)
14    ($lh:ty, {$rh:ty}, @$macro:ident) => {
15        all_combos!($lh, $rh, @$macro);
16    };
17    // Matches a single, wrapped lh and a plain rh: all_combos!({lh}, rh, @macro)
18    ({$lh:ty}, $rh:ty, @$macro:ident) => {
19           all_combos!($lh, $rh, @$macro);
20    };
21    // Matches a single, wrapped lh and a single, wrapped rh: all_combos!({lh}, {rh}, @macro)
22    ({$lh:ty}, {$rh:ty}, @$macro:ident) => {
23        all_combos!($lh, $rh, @$macro);
24    };
25    // Matches a plain lh and one+ rh: all_combos!(lh, {rh1, rh2, ...}, @macro)
26    ($lh:ty, {$first_rh:ty, $($rest_rh:ty),*}, @$macro:ident) => {
27        all_combos!($lh, $first_rh, @$macro);
28        all_combos!($lh, {$($rest_rh),*}, @$macro);
29    };
30    // Matches a single, wrapped lh and one+ rh: all_combos!({lh}, {rh1, ...}, @macro)
31    ({$lh:ty}, {$($rh:ty),*}, @$macro:ident) => {
32        all_combos!($lh, {$($rh),*}, @$macro)
33    };
34    // Matches one+ lh and one+ rh: all-combos!({lh1, lh2, ...}, {rh, ...}, @macro)
35    ({$first_lh:ty, $($rest_lh:ty),*}, {$($rh:ty),*}, @$macro:ident) => {
36        // Expand to the first lh and all of the rh
37        all_combos!($first_lh, {$($rh),*}, @$macro);
38        // Expand to the rest of the lh and all of the rh
39        all_combos!({$($rest_lh),*}, {$($rh),*}, @$macro);
40    };
41    // Matches one+ lh and a plain rh: all-combos!({lh1, lh2, ...}, rh, @macro)
42    ({$first_lh:ty, $($rest_lh:ty),*}, $rh:ty, @$macro:ident) => {
43        // Expand to the first lh and the rh
44        all_combos!($first_lh, $rh, @$macro);
45        // Expand to the rest of the lh and the rh
46        all_combos!({$($rest_lh),*}, $rh, @$macro);
47    };
48}
49
50// impl PartialEq<rh> and PartialOrd<rh> for <lh>
51macro_rules! impl_ordering {
52    ($lh:ty, $rh:ty) => {
53        impl PartialEq<$rh> for $lh {
54            fn eq(&self, other: &$rh) -> bool {
55                self.0.eq(other)
56            }
57        }
58        impl PartialOrd<$rh> for $lh {
59            fn partial_cmp(&self, other: &$rh) -> Option<core::cmp::Ordering> {
60                self.0.partial_cmp(other)
61            }
62        }
63    };
64}
65
66all_combos!({u1, u2, u3, u4, u5, u6, u7}, u8, @impl_ordering);
67all_combos!({u9, u10, u11, u12, u13, u14, u15}, u16, @impl_ordering);
68all_combos!({u17, u18, u19, u20, u21, u22, u23}, u32, @impl_ordering);
69all_combos!({u24, u25, u26, u27, u28, u29, u30, u31}, u32, @impl_ordering);
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn test_ordering() {
77        assert!(u1::new(1) > 0u8);
78        assert!(u10::new(10) > 0u16);
79        assert!(u20::new(10) > 0u32);
80    }
81}