1use crate::{ConvTo, Rounding};
9use core::convert::Infallible;
10
11#[macro_export]
27macro_rules! impl_via_identity {
28 ($x:ty) => {
29 impl $crate::ConvExact<$x> for $x {
30 type Error = ::core::convert::Infallible;
31
32 #[inline]
33 fn conv_exact(x: $x) -> Self {
34 x
35 }
36 #[inline]
37 fn try_conv_exact(x: $x) -> Result<Self, Self::Error> {
38 Ok(x)
39 }
40 }
41 };
42 ($x:ty $(, $xx:tt)* $(,)?) => {
43 $crate::impl_via_identity!($x);
44 $crate::impl_via_identity!($($xx),*);
45 };
46}
47
48#[rustfmt::skip]
49impl_via_identity!(
50 u8, u16, u32, u64, u128, usize,
51 i8, i16, i32, i64, i128, isize,
52 f32, f64,
53);
54
55#[macro_export]
79macro_rules! impl_via_from {
80 ($x:ty: $y:ty) => {
81 impl $crate::ConvExact<$x> for $y {
82 type Error = ::core::convert::Infallible;
83
84 #[inline]
85 fn conv_exact(x: $x) -> $y {
86 <$y>::from(x)
87 }
88 #[inline]
89 fn try_conv_exact(x: $x) -> Result<Self, Self::Error> {
90 Ok(<$y>::from(x))
91 }
92 }
93 };
94 ($x:ty: $y:ty, $($yy:ty),+) => {
95 $crate::impl_via_from!($x: $y);
96 $crate::impl_via_from!($x: $($yy),+);
97 };
98}
99
100impl_via_from!(i8: f32, f64, i16, i32, i64, i128, isize);
101impl_via_from!(i16: f32, f64, i32, i64, i128, isize);
102impl_via_from!(i32: f64, i64, i128);
103impl_via_from!(i64: i128);
104impl_via_from!(u8: f32, f64, i16, i32, i64, i128, isize);
105impl_via_from!(u8: u16, u32, u64, u128, usize);
106impl_via_from!(u16: f32, f64, i32, i64, i128, u32, u64, u128, usize);
107impl_via_from!(u32: f64, i64, i128, u64, u128);
108impl_via_from!(u64: i128, u128);
109
110impl<R: Rounding, S, T: ConvTo<S, R> + Copy + Default, const N: usize> ConvTo<[S; N], R>
113 for [T; N]
114{
115 type Error = T::Error;
116
117 #[inline]
118 fn try_conv_to(mode: R, ss: [S; N]) -> Result<Self, Self::Error> {
119 let mut tt = [T::default(); N];
120 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
121 *t = T::try_conv_to(mode, s)?;
122 }
123 Ok(tt)
124 }
125 #[inline]
126 fn conv_to(mode: R, ss: [S; N]) -> Self {
127 let mut tt = [T::default(); N];
128 for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
129 *t = T::conv_to(mode, s);
130 }
131 tt
132 }
133}
134
135impl<R: Rounding> ConvTo<(), R> for () {
136 type Error = Infallible;
137
138 #[inline]
139 fn try_conv_to(_: R, _: ()) -> Result<Self, Self::Error> {
140 Ok(())
141 }
142 #[inline]
143 fn conv_to(_: R, _: ()) -> Self {}
144}
145impl<R: Rounding, S0, T0: ConvTo<S0, R>> ConvTo<(S0,), R> for (T0,) {
146 type Error = T0::Error;
147
148 #[inline]
149 fn try_conv_to(mode: R, ss: (S0,)) -> Result<Self, Self::Error> {
150 Ok((T0::try_conv_to(mode, ss.0)?,))
151 }
152 #[inline]
153 fn conv_to(mode: R, ss: (S0,)) -> Self {
154 (T0::conv_to(mode, ss.0),)
155 }
156}
157impl<R: Rounding, S0, S1, T0: ConvTo<S0, R>, T1: ConvTo<S1, R>> ConvTo<(S0, S1), R> for (T0, T1) {
158 type Error = R::MaximumError;
159
160 #[inline]
161 fn try_conv_to(mode: R, ss: (S0, S1)) -> Result<Self, Self::Error> {
162 Ok((
163 T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
164 T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
165 ))
166 }
167 #[inline]
168 fn conv_to(mode: R, ss: (S0, S1)) -> Self {
169 (T0::conv_to(mode, ss.0), T1::conv_to(mode, ss.1))
170 }
171}
172impl<R: Rounding, S0, S1, S2, T0: ConvTo<S0, R>, T1: ConvTo<S1, R>, T2: ConvTo<S2, R>>
173 ConvTo<(S0, S1, S2), R> for (T0, T1, T2)
174{
175 type Error = R::MaximumError;
176
177 #[inline]
178 fn try_conv_to(mode: R, ss: (S0, S1, S2)) -> Result<Self, Self::Error> {
179 Ok((
180 T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
181 T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
182 T2::try_conv_to(mode, ss.2).map_err(Into::into)?,
183 ))
184 }
185 #[inline]
186 fn conv_to(mode: R, ss: (S0, S1, S2)) -> Self {
187 (
188 T0::conv_to(mode, ss.0),
189 T1::conv_to(mode, ss.1),
190 T2::conv_to(mode, ss.2),
191 )
192 }
193}
194impl<
195 R: Rounding,
196 S0,
197 S1,
198 S2,
199 S3,
200 T0: ConvTo<S0, R>,
201 T1: ConvTo<S1, R>,
202 T2: ConvTo<S2, R>,
203 T3: ConvTo<S3, R>,
204> ConvTo<(S0, S1, S2, S3), R> for (T0, T1, T2, T3)
205{
206 type Error = R::MaximumError;
207
208 #[inline]
209 fn try_conv_to(mode: R, ss: (S0, S1, S2, S3)) -> Result<Self, Self::Error> {
210 Ok((
211 T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
212 T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
213 T2::try_conv_to(mode, ss.2).map_err(Into::into)?,
214 T3::try_conv_to(mode, ss.3).map_err(Into::into)?,
215 ))
216 }
217 #[inline]
218 fn conv_to(mode: R, ss: (S0, S1, S2, S3)) -> Self {
219 (
220 T0::conv_to(mode, ss.0),
221 T1::conv_to(mode, ss.1),
222 T2::conv_to(mode, ss.2),
223 T3::conv_to(mode, ss.3),
224 )
225 }
226}
227impl<
228 R: Rounding,
229 S0,
230 S1,
231 S2,
232 S3,
233 S4,
234 T0: ConvTo<S0, R>,
235 T1: ConvTo<S1, R>,
236 T2: ConvTo<S2, R>,
237 T3: ConvTo<S3, R>,
238 T4: ConvTo<S4, R>,
239> ConvTo<(S0, S1, S2, S3, S4), R> for (T0, T1, T2, T3, T4)
240{
241 type Error = R::MaximumError;
242
243 #[inline]
244 fn try_conv_to(mode: R, ss: (S0, S1, S2, S3, S4)) -> Result<Self, Self::Error> {
245 Ok((
246 T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
247 T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
248 T2::try_conv_to(mode, ss.2).map_err(Into::into)?,
249 T3::try_conv_to(mode, ss.3).map_err(Into::into)?,
250 T4::try_conv_to(mode, ss.4).map_err(Into::into)?,
251 ))
252 }
253 #[inline]
254 fn conv_to(mode: R, ss: (S0, S1, S2, S3, S4)) -> Self {
255 (
256 T0::conv_to(mode, ss.0),
257 T1::conv_to(mode, ss.1),
258 T2::conv_to(mode, ss.2),
259 T3::conv_to(mode, ss.3),
260 T4::conv_to(mode, ss.4),
261 )
262 }
263}
264impl<R: Rounding, S0, S1, S2, S3, S4, S5, T0, T1, T2, T3, T4, T5>
265 ConvTo<(S0, S1, S2, S3, S4, S5), R> for (T0, T1, T2, T3, T4, T5)
266where
267 T0: ConvTo<S0, R>,
268 T1: ConvTo<S1, R>,
269 T2: ConvTo<S2, R>,
270 T3: ConvTo<S3, R>,
271 T4: ConvTo<S4, R>,
272 T5: ConvTo<S5, R>,
273{
274 type Error = R::MaximumError;
275
276 #[inline]
277 fn try_conv_to(mode: R, ss: (S0, S1, S2, S3, S4, S5)) -> Result<Self, Self::Error> {
278 Ok((
279 T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
280 T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
281 T2::try_conv_to(mode, ss.2).map_err(Into::into)?,
282 T3::try_conv_to(mode, ss.3).map_err(Into::into)?,
283 T4::try_conv_to(mode, ss.4).map_err(Into::into)?,
284 T5::try_conv_to(mode, ss.5).map_err(Into::into)?,
285 ))
286 }
287 #[inline]
288 fn conv_to(mode: R, ss: (S0, S1, S2, S3, S4, S5)) -> Self {
289 (
290 T0::conv_to(mode, ss.0),
291 T1::conv_to(mode, ss.1),
292 T2::conv_to(mode, ss.2),
293 T3::conv_to(mode, ss.3),
294 T4::conv_to(mode, ss.4),
295 T5::conv_to(mode, ss.5),
296 )
297 }
298}