1use std::mem;
2
3pub trait IntKey: Sized + Copy {
8 type Buf: AsRef<[u8]> + AsMut<[u8]> + Into<Vec<u8>> + Default;
9
10 fn to_cw_bytes(&self) -> Self::Buf;
11 fn from_cw_bytes(bytes: Self::Buf) -> Self;
12}
13
14macro_rules! cw_uint_keys {
15 (for $($t:ty),+) => {
16 $(impl IntKey for $t {
17 type Buf = [u8; mem::size_of::<$t>()];
18
19 #[inline]
20 fn to_cw_bytes(&self) -> Self::Buf {
21 self.to_be_bytes()
22 }
23
24 #[inline]
25 fn from_cw_bytes(bytes: Self::Buf) -> Self {
26 Self::from_be_bytes(bytes)
27 }
28 })*
29 }
30}
31
32cw_uint_keys!(for u8, u16, u32, u64, u128);
33
34macro_rules! cw_int_keys {
35 (for $($t:ty, $ut:ty),+) => {
36 $(impl IntKey for $t {
37 type Buf = [u8; mem::size_of::<$t>()];
38
39 #[inline]
40 fn to_cw_bytes(&self) -> Self::Buf {
41 (*self as $ut ^ <$t>::MIN as $ut).to_be_bytes()
42 }
43
44 #[inline]
45 fn from_cw_bytes(bytes: Self::Buf) -> Self {
46 (Self::from_be_bytes(bytes) as $ut ^ <$t>::MIN as $ut) as _
47 }
48 })*
49 }
50}
51
52cw_int_keys!(for i8, u8, i16, u16, i32, u32, i64, u64, i128, u128);
53
54#[cfg(test)]
55mod test {
56 use super::*;
57
58 #[test]
59 fn x8_int_key_works() {
60 assert_eq!(0x42u8.to_cw_bytes(), [0x42]);
61 assert_eq!(0x42i8.to_cw_bytes(), [0xc2]);
62 assert_eq!((-0x3ei8).to_cw_bytes(), [0x42]);
63 }
64
65 #[test]
66 fn x16_int_key_works() {
67 assert_eq!(0x4243u16.to_cw_bytes(), [0x42, 0x43]);
68 assert_eq!(0x4243i16.to_cw_bytes(), [0xc2, 0x43]);
69 assert_eq!((-0x3dbdi16).to_cw_bytes(), [0x42, 0x43]);
70 }
71
72 #[test]
73 fn x32_int_key_works() {
74 assert_eq!(0x424344u32.to_cw_bytes(), [0x00, 0x42, 0x43, 0x44]);
75 assert_eq!(0x424344i32.to_cw_bytes(), [0x80, 0x42, 0x43, 0x44]);
76 assert_eq!((-0x7fbdbcbci32).to_cw_bytes(), [0x00, 0x42, 0x43, 0x44]);
77 }
78
79 #[test]
80 fn x64_int_key_works() {
81 assert_eq!(
82 0x42434445u64.to_cw_bytes(),
83 [0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45]
84 );
85 assert_eq!(
86 0x42434445i64.to_cw_bytes(),
87 [0x80, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45]
88 );
89 assert_eq!(
90 (-0x7fffffffbdbcbbbbi64).to_cw_bytes(),
91 [0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44, 0x45]
92 );
93 }
94
95 #[test]
96 fn x128_int_key_works() {
97 assert_eq!(
98 0x4243444546u128.to_cw_bytes(),
99 [
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44,
101 0x45, 0x46
102 ]
103 );
104 assert_eq!(
105 0x4243444546i128.to_cw_bytes(),
106 [
107 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44,
108 0x45, 0x46
109 ]
110 );
111 assert_eq!(
112 (-0x7fffffffffffffffffffffbdbcbbbabai128).to_cw_bytes(),
113 [
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0x44,
115 0x45, 0x46
116 ]
117 );
118 }
119
120 #[test]
121 fn unsigned_int_key_order() {
122 assert!(0u32.to_cw_bytes() < 652u32.to_cw_bytes());
123 }
124
125 #[test]
126 fn signed_int_key_order() {
127 assert!((-321i32).to_cw_bytes() < 0i32.to_cw_bytes());
128 assert!(0i32.to_cw_bytes() < 652i32.to_cw_bytes());
129 }
130}