1use crate::pointer::Size;
2
3mod sealed {
4 pub trait Sealed<U: ?Sized> {}
5}
6
7pub trait CoerceSlice<U: ?Sized>: self::sealed::Sealed<U> {
14 #[doc(hidden)]
16 fn resize<O: Size>(factor: O) -> O;
17
18 #[doc(hidden)]
20 fn try_resize<O: Size>(factor: O) -> Option<O>;
21}
22
23macro_rules! self_impl_inner {
24 ($from:ty, {$($to:ty),*}) => {
25 $(
26 impl self::sealed::Sealed<[$to]> for [$from] {}
27
28 #[doc = concat!("Defines the coercion from `[", stringify!($from) ,"]` to `[", stringify!($to), "]`.")]
29 #[doc = concat!("let reference: Ref<", stringify!($from), "> = Ref::zero();")]
36 #[doc = concat!("let reference2 = reference.coerce::<[", stringify!($from), "]>();")]
37 #[doc = concat!("let reference3 = reference.coerce::<", stringify!($to), ">();")]
40 #[doc = concat!("let reference4 = reference2.coerce::<[", stringify!($to), "]>();")]
41 impl CoerceSlice<[$to]> for [$from] {
44 #[inline]
45 fn resize<O: Size>(len: O) -> O {
46 len
47 }
48
49 #[inline]
50 fn try_resize<O: Size>(len: O) -> Option<O> {
51 Some(len)
52 }
53 }
54 )*
55 }
56}
57
58macro_rules! self_impl {
59 ([$({$($from:ty),*}),*], [$($to:tt),*]) => {
60 $(
61 $(
62 self_impl_inner!($from, $to);
63 )*
64 )*
65 };
66}
67
68macro_rules! coerce_slice_inner {
69 ($factor:ident, $value:literal, $from:ty, {$($to:ty),*}) => {
70 $(
71 impl self::sealed::Sealed<[$to]> for [$from] {}
72
73 #[doc = concat!("Defines the coercion from `[", stringify!($from) ,"]` to `[", stringify!($to), "]`.")]
74 #[doc = concat!("let reference: Ref<", stringify!($from), "> = Ref::zero();")]
81 #[doc = concat!("let reference2 = reference.coerce::<[", stringify!($to), "]>();")]
82 #[doc = concat!("assert_eq!(reference2.len(), ", stringify!($value), ");")]
83 #[doc = concat!("let reference: Ref<[", stringify!($from), "]> = Ref::with_metadata(0, 5);")]
85 #[doc = concat!("let reference2 = reference.coerce::<[", stringify!($to), "]>();")]
86 #[doc = concat!("assert_eq!(reference2.len(), 5 * ", stringify!($value), ");")]
87 impl CoerceSlice<[$to]> for [$from] {
89 #[inline]
90 fn resize<O: Size>(len: O) -> O {
91 len.wrapping_mul(O::$factor)
92 }
93
94 #[inline]
95 fn try_resize<O: Size>(len: O) -> Option<O> {
96 len.checked_mul(O::$factor)
97 }
98 }
99 )*
100 }
101}
102
103macro_rules! coerce_slice {
104 ($factor:ident, $value:literal, [$({$($from:ty),*}),*], [$($to:tt),*]) => {
105 $(
106 $(
107 coerce_slice_inner!($factor, $value, $from, $to);
108 )*
109 )*
110 }
111}
112
113self_impl! {
114 [
115 {u8, i8},
116 {u16, i16},
117 {u32, i32},
118 {u64, i64},
119 {u128, i128}
120 ],
121 [
122 {u8, i8},
123 {u16, i16, [u8; 2], [i8; 2]},
124 {u32, i32, [u16; 2], [i16; 2], [u8; 4], [i8; 4]},
125 {u64, i64, [u32; 2], [i32; 2], [u16; 4], [i16; 4], [u8; 8], [i8; 8]},
126 {u128, i128, [u64; 2], [i64; 2], [u32; 4], [i32; 4], [u16; 8], [i16; 8], [u8; 16], [i8; 16]}
127 ]
128}
129
130coerce_slice! {
131 N2, 2,
132 [
133 {u16, i16},
134 {u32, i32},
135 {u64, i64},
136 {u128, i128}
137 ],
138 [
139 {u8, i8},
140 {u16, i16, [u8; 2], [i8; 2]},
141 {u32, i32, [u16; 2], [i16; 2], [u8; 4], [i8; 4]},
142 {u64, i64, [u32; 2], [i32; 2], [u16; 4], [i16; 4], [u8; 8], [i8; 8]}
143 ]
144}
145
146coerce_slice! {
147 N4, 4,
148 [
149 {u32, i32},
150 {u64, i64},
151 {u128, i128}
152 ],
153 [
154 {u8, i8},
155 {u16, i16, [u8; 2], [i8; 2]},
156 {u32, i32, [u16; 2], [i16; 2], [u8; 4], [i8; 4]}
157 ]
158}
159
160coerce_slice! {
161 N8, 8,
162 [
163 {u64, i64},
164 {u128, i128}
165 ],
166 [
167 {u8, i8},
168 {u16, i16, [u8; 2], [i8; 2]}
169 ]
170}
171
172coerce_slice! {
173 N16, 16,
174 [
175 {u128, i128}
176 ],
177 [
178 {u8, i8}
179 ]
180}