1use crate::altrep_traits::{NA_INTEGER, NA_LOGICAL, NA_REAL};
43use crate::{IsNA, Rboolean, Rcomplex};
44
45pub trait Coerce<R> {
65 fn coerce(self) -> R;
69}
70
71pub trait TryCoerce<R> {
78 type Error;
80 fn try_coerce(self) -> Result<R, Self::Error>;
82}
83
84#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CoerceError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CoerceError::Overflow => "Overflow",
CoerceError::PrecisionLoss => "PrecisionLoss",
CoerceError::NaN => "NaN",
CoerceError::Zero => "Zero",
})
}
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for CoerceError { }
#[automatically_derived]
impl ::core::clone::Clone for CoerceError {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CoerceError { }Copy, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for CoerceError { }
#[automatically_derived]
impl ::core::cmp::PartialEq for CoerceError {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CoerceError { }Eq)]
86pub enum CoerceError {
87 Overflow,
89 PrecisionLoss,
91 NaN,
93 Zero,
95}
96
97impl std::fmt::Display for CoerceError {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 match self {
100 CoerceError::Overflow => f.write_fmt(format_args!("value out of range"))write!(f, "value out of range"),
101 CoerceError::PrecisionLoss => f.write_fmt(format_args!("precision loss"))write!(f, "precision loss"),
102 CoerceError::NaN => f.write_fmt(format_args!("NaN cannot be converted"))write!(f, "NaN cannot be converted"),
103 CoerceError::Zero => f.write_fmt(format_args!("zero not allowed"))write!(f, "zero not allowed"),
104 }
105 }
106}
107
108impl std::error::Error for CoerceError {}
109
110impl<T, R> TryCoerce<R> for T
113where
114 T: Coerce<R>,
115{
116 type Error = std::convert::Infallible;
117
118 #[inline(always)]
119 fn try_coerce(self) -> Result<R, Self::Error> {
120 Ok(self.coerce())
121 }
122}
123macro_rules! impl_identity {
132 ($t:ty) => {
133 impl Coerce<$t> for $t {
134 #[inline(always)]
135 fn coerce(self) -> $t {
136 self
137 }
138 }
139 };
140}
141
142impl Coerce<i32> for i32 {
#[inline(always)]
fn coerce(self) -> i32 { self }
}impl_identity!(i32);
143impl Coerce<f64> for f64 {
#[inline(always)]
fn coerce(self) -> f64 { self }
}impl_identity!(f64);
144impl Coerce<Rboolean> for Rboolean {
#[inline(always)]
fn coerce(self) -> Rboolean { self }
}impl_identity!(Rboolean);
145impl Coerce<u8> for u8 {
#[inline(always)]
fn coerce(self) -> u8 { self }
}impl_identity!(u8);
146impl Coerce<Rcomplex> for Rcomplex {
#[inline(always)]
fn coerce(self) -> Rcomplex { self }
}impl_identity!(Rcomplex);
147macro_rules! impl_widen {
156 ($($from:ty => $to:ty),+ $(,)?) => {
157 $(
158 impl Coerce<$to> for $from {
159 #[inline(always)]
160 fn coerce(self) -> $to {
161 self.into()
162 }
163 }
164 )+
165 };
166}
167
168macro_rules! impl_try_narrow {
171 ($target:ty; $($from:ty),+ $(,)?) => {
172 $(
173 impl TryCoerce<$target> for $from {
174 type Error = CoerceError;
175 #[inline]
176 fn try_coerce(self) -> Result<$target, CoerceError> {
177 self.try_into().map_err(|_| CoerceError::Overflow)
178 }
179 }
180 )+
181 };
182}
183impl<T: crate::markers::WidensToI32> Coerce<i32> for T {
192 #[inline(always)]
193 fn coerce(self) -> i32 {
194 self.into()
195 }
196}
197
198impl<T: crate::markers::WidensToF64> Coerce<f64> for T {
203 #[inline(always)]
204 fn coerce(self) -> f64 {
205 self.into()
206 }
207}
208impl Coerce<i64> for u8 {
#[inline(always)]
fn coerce(self) -> i64 { self.into() }
}
impl Coerce<isize> for u8 {
#[inline(always)]
fn coerce(self) -> isize { self.into() }
}
impl Coerce<u64> for u8 {
#[inline(always)]
fn coerce(self) -> u64 { self.into() }
}
impl Coerce<usize> for u8 {
#[inline(always)]
fn coerce(self) -> usize { self.into() }
}
impl Coerce<f32> for u8 {
#[inline(always)]
fn coerce(self) -> f32 { self.into() }
}impl_widen!(u8 => i64, u8 => isize, u8 => u64, u8 => usize, u8 => f32);
213
214impl Coerce<f32> for i32 {
215 #[inline(always)]
216 fn coerce(self) -> f32 {
217 self as f32
218 }
219}
220impl Coerce<Rboolean> for bool {
225 #[inline(always)]
226 fn coerce(self) -> Rboolean {
227 if self {
228 Rboolean::TRUE
229 } else {
230 Rboolean::FALSE
231 }
232 }
233}
234
235impl Coerce<i32> for bool {
236 #[inline(always)]
237 fn coerce(self) -> i32 {
238 if self { 1 } else { 0 }
239 }
240}
241
242impl Coerce<f64> for bool {
243 #[inline(always)]
244 fn coerce(self) -> f64 {
245 if self { 1.0 } else { 0.0 }
246 }
247}
248
249impl Coerce<i32> for Rboolean {
250 #[inline(always)]
251 fn coerce(self) -> i32 {
252 self as i32
253 }
254}
255impl Coerce<f64> for Option<f64> {
261 #[inline(always)]
262 fn coerce(self) -> f64 {
263 self.unwrap_or(NA_REAL)
264 }
265}
266
267impl Coerce<i32> for Option<i32> {
269 #[inline(always)]
270 fn coerce(self) -> i32 {
271 self.unwrap_or(NA_INTEGER)
272 }
273}
274
275impl Coerce<i32> for Option<bool> {
277 #[inline(always)]
278 fn coerce(self) -> i32 {
279 match self {
280 Some(true) => 1,
281 Some(false) => 0,
282 None => NA_LOGICAL,
283 }
284 }
285}
286
287impl Coerce<i32> for Option<Rboolean> {
289 #[inline(always)]
290 fn coerce(self) -> i32 {
291 match self {
292 Some(v) => v as i32,
293 None => NA_LOGICAL,
294 }
295 }
296}
297impl Coerce<i64> for i32 {
303 #[inline(always)]
304 fn coerce(self) -> i64 {
305 self.into()
306 }
307}
308
309impl Coerce<isize> for i32 {
311 #[inline(always)]
312 fn coerce(self) -> isize {
313 self as isize
314 }
315}
316
317impl TryCoerce<u32> for i32 {
319 type Error = CoerceError;
320
321 #[inline]
322 fn try_coerce(self) -> Result<u32, CoerceError> {
323 self.try_into().map_err(|_| CoerceError::Overflow)
324 }
325}
326
327impl TryCoerce<u64> for i32 {
329 type Error = CoerceError;
330
331 #[inline]
332 fn try_coerce(self) -> Result<u64, CoerceError> {
333 self.try_into().map_err(|_| CoerceError::Overflow)
334 }
335}
336
337impl TryCoerce<usize> for i32 {
339 type Error = CoerceError;
340
341 #[inline]
342 fn try_coerce(self) -> Result<usize, CoerceError> {
343 self.try_into().map_err(|_| CoerceError::Overflow)
344 }
345}
346use core::num::{
351 NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroIsize, NonZeroU8, NonZeroU16, NonZeroU32,
352 NonZeroU64, NonZeroUsize,
353};
354
355macro_rules! impl_nonzero_from_self {
356 ($base:ty, $nz:ty) => {
357 impl TryCoerce<$nz> for $base {
358 type Error = CoerceError;
359
360 #[inline]
361 fn try_coerce(self) -> Result<$nz, CoerceError> {
362 <$nz>::new(self).ok_or(CoerceError::Zero)
363 }
364 }
365 };
366}
367
368impl TryCoerce<NonZeroI8> for i8 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroI8, CoerceError> {
<NonZeroI8>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(i8, NonZeroI8);
370impl TryCoerce<NonZeroI16> for i16 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroI16, CoerceError> {
<NonZeroI16>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(i16, NonZeroI16);
371impl TryCoerce<NonZeroI32> for i32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroI32, CoerceError> {
<NonZeroI32>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(i32, NonZeroI32);
372impl TryCoerce<NonZeroI64> for i64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroI64, CoerceError> {
<NonZeroI64>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(i64, NonZeroI64);
373impl TryCoerce<NonZeroIsize> for isize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroIsize, CoerceError> {
<NonZeroIsize>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(isize, NonZeroIsize);
374impl TryCoerce<NonZeroU8> for u8 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroU8, CoerceError> {
<NonZeroU8>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(u8, NonZeroU8);
375impl TryCoerce<NonZeroU16> for u16 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroU16, CoerceError> {
<NonZeroU16>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(u16, NonZeroU16);
376impl TryCoerce<NonZeroU32> for u32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroU32, CoerceError> {
<NonZeroU32>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(u32, NonZeroU32);
377impl TryCoerce<NonZeroU64> for u64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroU64, CoerceError> {
<NonZeroU64>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(u64, NonZeroU64);
378impl TryCoerce<NonZeroUsize> for usize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<NonZeroUsize, CoerceError> {
<NonZeroUsize>::new(self).ok_or(CoerceError::Zero)
}
}impl_nonzero_from_self!(usize, NonZeroUsize);
379
380impl TryCoerce<NonZeroI64> for i32 {
382 type Error = CoerceError;
383
384 #[inline]
385 fn try_coerce(self) -> Result<NonZeroI64, CoerceError> {
386 NonZeroI64::new(self.into()).ok_or(CoerceError::Zero)
387 }
388}
389
390impl TryCoerce<NonZeroIsize> for i32 {
392 type Error = CoerceError;
393
394 #[inline]
395 fn try_coerce(self) -> Result<NonZeroIsize, CoerceError> {
396 NonZeroIsize::new(self as isize).ok_or(CoerceError::Zero)
397 }
398}
399
400impl TryCoerce<NonZeroU32> for i32 {
402 type Error = CoerceError;
403
404 #[inline]
405 fn try_coerce(self) -> Result<NonZeroU32, CoerceError> {
406 let u: u32 = self.try_into().map_err(|_| CoerceError::Overflow)?;
407 NonZeroU32::new(u).ok_or(CoerceError::Zero)
408 }
409}
410
411impl TryCoerce<NonZeroU64> for i32 {
413 type Error = CoerceError;
414
415 #[inline]
416 fn try_coerce(self) -> Result<NonZeroU64, CoerceError> {
417 let u: u64 = self.try_into().map_err(|_| CoerceError::Overflow)?;
418 NonZeroU64::new(u).ok_or(CoerceError::Zero)
419 }
420}
421
422impl TryCoerce<NonZeroUsize> for i32 {
424 type Error = CoerceError;
425
426 #[inline]
427 fn try_coerce(self) -> Result<NonZeroUsize, CoerceError> {
428 let u: usize = self.try_into().map_err(|_| CoerceError::Overflow)?;
429 NonZeroUsize::new(u).ok_or(CoerceError::Zero)
430 }
431}
432
433impl TryCoerce<NonZeroI8> for i32 {
435 type Error = CoerceError;
436
437 #[inline]
438 fn try_coerce(self) -> Result<NonZeroI8, CoerceError> {
439 let n: i8 = self.try_into().map_err(|_| CoerceError::Overflow)?;
440 NonZeroI8::new(n).ok_or(CoerceError::Zero)
441 }
442}
443
444impl TryCoerce<NonZeroI16> for i32 {
446 type Error = CoerceError;
447
448 #[inline]
449 fn try_coerce(self) -> Result<NonZeroI16, CoerceError> {
450 let n: i16 = self.try_into().map_err(|_| CoerceError::Overflow)?;
451 NonZeroI16::new(n).ok_or(CoerceError::Zero)
452 }
453}
454
455impl TryCoerce<NonZeroU8> for i32 {
457 type Error = CoerceError;
458
459 #[inline]
460 fn try_coerce(self) -> Result<NonZeroU8, CoerceError> {
461 let u: u8 = self.try_into().map_err(|_| CoerceError::Overflow)?;
462 NonZeroU8::new(u).ok_or(CoerceError::Zero)
463 }
464}
465
466impl TryCoerce<NonZeroU16> for i32 {
468 type Error = CoerceError;
469
470 #[inline]
471 fn try_coerce(self) -> Result<NonZeroU16, CoerceError> {
472 let u: u16 = self.try_into().map_err(|_| CoerceError::Overflow)?;
473 NonZeroU16::new(u).ok_or(CoerceError::Zero)
474 }
475}
476#[derive(#[automatically_derived]
impl ::core::fmt::Debug for LogicalCoerceError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::NAValue => ::core::fmt::Formatter::write_str(f, "NAValue"),
Self::InvalidValue(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidValue", &__self_0),
}
}
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for LogicalCoerceError { }
#[automatically_derived]
impl ::core::clone::Clone for LogicalCoerceError {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<i32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LogicalCoerceError { }Copy, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for LogicalCoerceError { }
#[automatically_derived]
impl ::core::cmp::PartialEq for LogicalCoerceError {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other) &&
match (self, other) {
(Self::InvalidValue(__self_0), Self::InvalidValue(__arg1_0))
=> __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for LogicalCoerceError {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<i32>;
}
}Eq)]
482pub enum LogicalCoerceError {
483 NAValue,
485 InvalidValue(i32),
487}
488
489impl std::fmt::Display for LogicalCoerceError {
490 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
491 match self {
492 LogicalCoerceError::NAValue => f.write_fmt(format_args!("NA is not allowed"))write!(f, "NA is not allowed"),
493 LogicalCoerceError::InvalidValue(v) => f.write_fmt(format_args!("{0} is neither 0 nor 1", v))write!(f, "{v} is neither 0 nor 1"),
494 }
495 }
496}
497
498impl std::error::Error for LogicalCoerceError {}
499
500impl TryCoerce<bool> for i32 {
501 type Error = LogicalCoerceError;
502
503 #[inline]
504 fn try_coerce(self) -> Result<bool, LogicalCoerceError> {
505 match self {
506 0 => Ok(false),
507 1 => Ok(true),
508 v if v.is_na() => Err(LogicalCoerceError::NAValue),
510 other => Err(LogicalCoerceError::InvalidValue(other)),
511 }
512 }
513}
514
515impl TryCoerce<bool> for Rboolean {
516 type Error = LogicalCoerceError;
517
518 #[inline]
519 fn try_coerce(self) -> Result<bool, LogicalCoerceError> {
520 (self as i32).try_coerce()
521 }
522}
523
524impl TryCoerce<bool> for crate::RLogical {
525 type Error = LogicalCoerceError;
526
527 #[inline]
528 fn try_coerce(self) -> Result<bool, LogicalCoerceError> {
529 self.to_i32().try_coerce()
530 }
531}
532impl TryCoerce<i32> for u32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i32, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i32> for u64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i32, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i32> for usize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i32, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i32> for i64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i32, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i32> for isize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i32, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}impl_try_narrow!(i32; u32, u64, usize, i64, isize);
537impl TryCoerce<u8> for i8 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u8> for i16 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u8> for i32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u8> for i64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u8> for u16 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u8> for u32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u8> for u64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u8> for usize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u8> for isize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}impl_try_narrow!(u8; i8, i16, i32, i64, u16, u32, u64, usize, isize);
542impl Coerce<u16> for u8 {
#[inline(always)]
fn coerce(self) -> u16 { self.into() }
}
impl Coerce<i16> for i8 {
#[inline(always)]
fn coerce(self) -> i16 { self.into() }
}
impl Coerce<i16> for u8 {
#[inline(always)]
fn coerce(self) -> i16 { self.into() }
}
impl Coerce<u32> for u8 {
#[inline(always)]
fn coerce(self) -> u32 { self.into() }
}
impl Coerce<u32> for u16 {
#[inline(always)]
fn coerce(self) -> u32 { self.into() }
}impl_widen!(u8 => u16, i8 => i16, u8 => i16, u8 => u32, u16 => u32);
547impl TryCoerce<u16> for i8 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u16> for i16 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u16> for i32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u16> for i64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u16> for u32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u16> for u64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u16> for usize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<u16> for isize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<u16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}impl_try_narrow!(u16; i8, i16, i32, i64, u32, u64, usize, isize);
552impl TryCoerce<i16> for i32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i16> for i64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i16> for u16 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i16> for u32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i16> for u64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i16> for usize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i16> for isize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i16, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}impl_try_narrow!(i16; i32, i64, u16, u32, u64, usize, isize);
557impl TryCoerce<i8> for i16 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i8> for i32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i8> for i64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i8> for u8 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i8> for u16 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i8> for u32 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i8> for u64 {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i8> for usize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}
impl TryCoerce<i8> for isize {
type Error = CoerceError;
#[inline]
fn try_coerce(self) -> Result<i8, CoerceError> {
self.try_into().map_err(|_| CoerceError::Overflow)
}
}impl_try_narrow!(i8; i16, i32, i64, u8, u16, u32, u64, usize, isize);
562impl TryCoerce<u16> for f64 {
567 type Error = CoerceError;
568
569 #[inline]
570 fn try_coerce(self) -> Result<u16, CoerceError> {
571 if self.is_nan() {
572 return Err(CoerceError::NaN);
573 }
574 if self.is_infinite() {
575 return Err(CoerceError::Overflow);
576 }
577 if self < 0.0 || self > u16::MAX as f64 {
578 return Err(CoerceError::Overflow);
579 }
580 if self.fract() != 0.0 {
581 return Err(CoerceError::PrecisionLoss);
582 }
583 Ok(self as u16)
584 }
585}
586
587impl TryCoerce<i16> for f64 {
588 type Error = CoerceError;
589
590 #[inline]
591 fn try_coerce(self) -> Result<i16, CoerceError> {
592 if self.is_nan() {
593 return Err(CoerceError::NaN);
594 }
595 if self.is_infinite() {
596 return Err(CoerceError::Overflow);
597 }
598 if self < i16::MIN as f64 || self > i16::MAX as f64 {
599 return Err(CoerceError::Overflow);
600 }
601 if self.fract() != 0.0 {
602 return Err(CoerceError::PrecisionLoss);
603 }
604 Ok(self as i16)
605 }
606}
607
608impl TryCoerce<i8> for f64 {
609 type Error = CoerceError;
610
611 #[inline]
612 fn try_coerce(self) -> Result<i8, CoerceError> {
613 if self.is_nan() {
614 return Err(CoerceError::NaN);
615 }
616 if self.is_infinite() {
617 return Err(CoerceError::Overflow);
618 }
619 if self < i8::MIN as f64 || self > i8::MAX as f64 {
620 return Err(CoerceError::Overflow);
621 }
622 if self.fract() != 0.0 {
623 return Err(CoerceError::PrecisionLoss);
624 }
625 Ok(self as i8)
626 }
627}
628impl TryCoerce<i32> for f64 {
636 type Error = CoerceError;
637
638 #[inline]
639 fn try_coerce(self) -> Result<i32, CoerceError> {
640 if self.is_nan() {
641 return Err(CoerceError::NaN);
642 }
643 if self.is_infinite() {
644 return Err(CoerceError::Overflow);
645 }
646 if self <= i32::MIN as f64 || self > i32::MAX as f64 {
647 return Err(CoerceError::Overflow);
648 }
649 if self.fract() != 0.0 {
650 return Err(CoerceError::PrecisionLoss);
651 }
652 Ok(self as i32)
653 }
654}
655
656impl TryCoerce<i32> for f32 {
657 type Error = CoerceError;
658
659 #[inline]
660 fn try_coerce(self) -> Result<i32, CoerceError> {
661 f64::from(self).try_coerce()
662 }
663}
664
665impl Coerce<f32> for f64 {
667 #[inline(always)]
668 fn coerce(self) -> f32 {
669 self as f32
670 }
671}
672impl TryCoerce<u8> for f64 {
677 type Error = CoerceError;
678
679 #[inline]
680 fn try_coerce(self) -> Result<u8, CoerceError> {
681 if self.is_nan() {
682 return Err(CoerceError::NaN);
683 }
684 if self.is_infinite() {
685 return Err(CoerceError::Overflow);
686 }
687 if self < 0.0 || self > u8::MAX as f64 {
688 return Err(CoerceError::Overflow);
689 }
690 if self.fract() != 0.0 {
691 return Err(CoerceError::PrecisionLoss);
692 }
693 Ok(self as u8)
694 }
695}
696
697impl TryCoerce<u8> for f32 {
698 type Error = CoerceError;
699
700 #[inline]
701 fn try_coerce(self) -> Result<u8, CoerceError> {
702 f64::from(self).try_coerce()
703 }
704}
705impl TryCoerce<u32> for f64 {
710 type Error = CoerceError;
711
712 #[inline]
713 fn try_coerce(self) -> Result<u32, CoerceError> {
714 if self.is_nan() {
715 return Err(CoerceError::NaN);
716 }
717 if self.is_infinite() {
718 return Err(CoerceError::Overflow);
719 }
720 if self < 0.0 || self > u32::MAX as f64 {
721 return Err(CoerceError::Overflow);
722 }
723 if self.fract() != 0.0 {
724 return Err(CoerceError::PrecisionLoss);
725 }
726 Ok(self as u32)
727 }
728}
729impl TryCoerce<i64> for f64 {
750 type Error = CoerceError;
751
752 #[inline]
753 fn try_coerce(self) -> Result<i64, CoerceError> {
754 if self.is_nan() {
755 return Err(CoerceError::NaN);
756 }
757 if self.is_infinite() {
758 return Err(CoerceError::Overflow);
759 }
760 if self < i64::MIN as f64 || self >= i64::MAX as f64 {
762 return Err(CoerceError::Overflow);
763 }
764 if self.fract() != 0.0 {
765 return Err(CoerceError::PrecisionLoss);
766 }
767 Ok(self as i64)
768 }
769}
770
771impl TryCoerce<u64> for f64 {
772 type Error = CoerceError;
773
774 #[inline]
775 fn try_coerce(self) -> Result<u64, CoerceError> {
776 if self.is_nan() {
777 return Err(CoerceError::NaN);
778 }
779 if self.is_infinite() {
780 return Err(CoerceError::Overflow);
781 }
782 if self < 0.0 || self >= u64::MAX as f64 {
783 return Err(CoerceError::Overflow);
784 }
785 if self.fract() != 0.0 {
786 return Err(CoerceError::PrecisionLoss);
787 }
788 Ok(self as u64)
789 }
790}
791
792impl TryCoerce<isize> for f64 {
793 type Error = CoerceError;
794
795 #[inline]
796 fn try_coerce(self) -> Result<isize, CoerceError> {
797 if self.is_nan() {
798 return Err(CoerceError::NaN);
799 }
800 if self.is_infinite() {
801 return Err(CoerceError::Overflow);
802 }
803 if self < isize::MIN as f64 || self >= isize::MAX as f64 {
805 return Err(CoerceError::Overflow);
806 }
807 if self.fract() != 0.0 {
808 return Err(CoerceError::PrecisionLoss);
809 }
810 Ok(self as isize)
811 }
812}
813
814impl TryCoerce<usize> for f64 {
815 type Error = CoerceError;
816
817 #[inline]
818 fn try_coerce(self) -> Result<usize, CoerceError> {
819 if self.is_nan() {
820 return Err(CoerceError::NaN);
821 }
822 if self.is_infinite() {
823 return Err(CoerceError::Overflow);
824 }
825 if self < 0.0 || self >= usize::MAX as f64 {
827 return Err(CoerceError::Overflow);
828 }
829 if self.fract() != 0.0 {
830 return Err(CoerceError::PrecisionLoss);
831 }
832 Ok(self as usize)
833 }
834}
835impl TryCoerce<f64> for i64 {
856 type Error = CoerceError;
857
858 #[inline]
859 fn try_coerce(self) -> Result<f64, CoerceError> {
860 const MAX_SAFE: i64 = 1 << 53;
861 const MIN_SAFE: i64 = -(1 << 53);
862 if !(MIN_SAFE..=MAX_SAFE).contains(&self) {
863 return Err(CoerceError::PrecisionLoss);
864 }
865 Ok(self as f64)
866 }
867}
868
869impl TryCoerce<f64> for u64 {
873 type Error = CoerceError;
874
875 #[inline]
876 fn try_coerce(self) -> Result<f64, CoerceError> {
877 const MAX_SAFE: u64 = 1 << 53;
878 if self > MAX_SAFE {
879 return Err(CoerceError::PrecisionLoss);
880 }
881 Ok(self as f64)
882 }
883}
884
885impl TryCoerce<f64> for isize {
886 type Error = CoerceError;
887 #[inline]
888 fn try_coerce(self) -> Result<f64, CoerceError> {
889 (self as i64).try_coerce()
890 }
891}
892
893impl TryCoerce<f64> for usize {
894 type Error = CoerceError;
895 #[inline]
896 fn try_coerce(self) -> Result<f64, CoerceError> {
897 (self as u64).try_coerce()
898 }
899}
900use std::marker::PhantomData;
905
906#[repr(transparent)]
922#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug, R: ::core::fmt::Debug> ::core::fmt::Debug for
Coerced<T, R> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Coerced",
"value", &self.value, "_marker", &&self._marker)
}
}Debug, #[automatically_derived]
impl<T: ::core::clone::Clone, R: ::core::clone::Clone> ::core::clone::Clone
for Coerced<T, R> {
#[inline]
fn clone(&self) -> Self {
Coerced {
value: ::core::clone::Clone::clone(&self.value),
_marker: ::core::clone::Clone::clone(&self._marker),
}
}
}Clone, #[automatically_derived]
impl<T: ::core::marker::Copy, R: ::core::marker::Copy> ::core::marker::Copy
for Coerced<T, R> {
}Copy, #[automatically_derived]
impl<T: ::core::cmp::PartialEq, R: ::core::cmp::PartialEq>
::core::marker::StructuralPartialEq for Coerced<T, R> {
}
#[automatically_derived]
impl<T: ::core::cmp::PartialEq, R: ::core::cmp::PartialEq>
::core::cmp::PartialEq for Coerced<T, R> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.value == other.value && self._marker == other._marker
}
}PartialEq, #[automatically_derived]
impl<T: ::core::cmp::Eq, R: ::core::cmp::Eq> ::core::cmp::Eq for Coerced<T, R>
{
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<T>;
let _: ::core::cmp::AssertParamIsEq<PhantomData<R>>;
}
}Eq, #[automatically_derived]
impl<T: ::core::cmp::PartialOrd, R: ::core::cmp::PartialOrd>
::core::cmp::PartialOrd for Coerced<T, R> {
#[inline]
fn partial_cmp(&self, other: &Self)
-> ::core::option::Option<::core::cmp::Ordering> {
match ::core::cmp::PartialOrd::partial_cmp(&self.value, &other.value)
{
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
::core::cmp::PartialOrd::partial_cmp(&self._marker,
&other._marker),
cmp => cmp,
}
}
}PartialOrd, #[automatically_derived]
impl<T: ::core::cmp::Ord, R: ::core::cmp::Ord> ::core::cmp::Ord for
Coerced<T, R> {
#[inline]
fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.value, &other.value) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self._marker, &other._marker),
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl<T: ::core::hash::Hash, R: ::core::hash::Hash> ::core::hash::Hash for
Coerced<T, R> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.value, state);
::core::hash::Hash::hash(&self._marker, state)
}
}Hash, #[automatically_derived]
impl<T: ::core::default::Default, R: ::core::default::Default>
::core::default::Default for Coerced<T, R> {
#[inline]
fn default() -> Self {
Coerced {
value: ::core::default::Default::default(),
_marker: ::core::default::Default::default(),
}
}
}Default)]
923pub struct Coerced<T, R> {
924 value: T,
925 _marker: PhantomData<R>,
926}
927
928impl<T, R> Coerced<T, R> {
929 #[inline]
931 pub const fn new(value: T) -> Self {
932 Self {
933 value,
934 _marker: PhantomData,
935 }
936 }
937
938 #[inline]
940 pub fn into_inner(self) -> T {
941 self.value
942 }
943
944 #[inline]
946 pub const fn as_inner(&self) -> &T {
947 &self.value
948 }
949
950 #[inline]
952 pub fn as_inner_mut(&mut self) -> &mut T {
953 &mut self.value
954 }
955}
956
957impl<T, R> std::ops::Deref for Coerced<T, R> {
958 type Target = T;
959
960 #[inline]
961 fn deref(&self) -> &Self::Target {
962 &self.value
963 }
964}
965
966impl<T, R> std::ops::DerefMut for Coerced<T, R> {
967 #[inline]
968 fn deref_mut(&mut self) -> &mut Self::Target {
969 &mut self.value
970 }
971}
972impl<T: Copy + Coerce<R>, R> Coerce<Vec<R>> for &[T] {
978 #[inline]
979 fn coerce(self) -> Vec<R> {
980 self.iter().copied().map(Coerce::coerce).collect()
981 }
982}
983
984impl<T: Coerce<R>, R> Coerce<Vec<R>> for Vec<T> {
986 #[inline]
987 fn coerce(self) -> Vec<R> {
988 self.into_iter().map(Coerce::coerce).collect()
989 }
990}
991
992impl<T: Coerce<R>, R> Coerce<Box<[R]>> for Box<[T]> {
994 #[inline]
995 fn coerce(self) -> Box<[R]> {
996 Vec::from(self).into_iter().map(Coerce::coerce).collect()
997 }
998}
999
1000impl<T: Coerce<R>, R> Coerce<std::collections::VecDeque<R>> for std::collections::VecDeque<T> {
1002 fn coerce(self) -> std::collections::VecDeque<R> {
1003 self.into_iter().map(Coerce::coerce).collect()
1004 }
1005}
1006
1007#[cfg(feature = "tinyvec")]
1016impl<T, R, const N: usize> Coerce<tinyvec::TinyVec<[R; N]>> for tinyvec::TinyVec<[T; N]>
1020where
1021 T: Coerce<R>,
1022 [T; N]: tinyvec::Array<Item = T>,
1023 [R; N]: tinyvec::Array<Item = R>,
1024{
1025 fn coerce(self) -> tinyvec::TinyVec<[R; N]> {
1026 self.into_iter().map(Coerce::coerce).collect()
1027 }
1028}
1029
1030#[cfg(feature = "tinyvec")]
1031impl<T, R, const N: usize> Coerce<tinyvec::ArrayVec<[R; N]>> for tinyvec::ArrayVec<[T; N]>
1035where
1036 T: Coerce<R>,
1037 [T; N]: tinyvec::Array<Item = T>,
1038 [R; N]: tinyvec::Array<Item = R>,
1039{
1040 fn coerce(self) -> tinyvec::ArrayVec<[R; N]> {
1041 self.into_iter().map(Coerce::coerce).collect()
1042 }
1043}
1044macro_rules! impl_tuple_coerce {
1050 ($n:literal, $name:literal; $($T:ident $R:ident $idx:tt),+) => {
1051 impl<$($T,)+ $($R,)+> Coerce<($($R,)+)> for ($($T,)+)
1052 where
1053 $($T: Coerce<$R>,)+
1054 {
1055 #[inline]
1056 fn coerce(self) -> ($($R,)+) {
1057 ($(Coerce::<$R>::coerce(self.$idx),)+)
1058 }
1059 }
1060 };
1061}
1062
1063impl<A, B, C, D, E, F, G, H, I, J, K, L, RA, RB, RC, RD, RE, RF, RG, RH, RI,
RJ, RK, RL> Coerce<(RA, RB, RC, RD, RE, RF, RG, RH, RI, RJ, RK, RL)> for
(A, B, C, D, E, F, G, H, I, J, K, L) where A: Coerce<RA>, B: Coerce<RB>,
C: Coerce<RC>, D: Coerce<RD>, E: Coerce<RE>, F: Coerce<RF>, G: Coerce<RG>,
H: Coerce<RH>, I: Coerce<RI>, J: Coerce<RJ>, K: Coerce<RK>, L: Coerce<RL>
{
#[inline]
fn coerce(self) -> (RA, RB, RC, RD, RE, RF, RG, RH, RI, RJ, RK, RL) {
(Coerce::<RA>::coerce(self.0), Coerce::<RB>::coerce(self.1),
Coerce::<RC>::coerce(self.2), Coerce::<RD>::coerce(self.3),
Coerce::<RE>::coerce(self.4), Coerce::<RF>::coerce(self.5),
Coerce::<RG>::coerce(self.6), Coerce::<RH>::coerce(self.7),
Coerce::<RI>::coerce(self.8), Coerce::<RJ>::coerce(self.9),
Coerce::<RK>::coerce(self.10), Coerce::<RL>::coerce(self.11))
}
}crate::tuple_macros::for_each_tuple!(impl_tuple_coerce);
1064#[cfg(test)]
1069mod tests;
1070