az/
lib.rs

1// Copyright © 2019–2021 Trevor Spiteri
2
3// This library is free software: you can redistribute it and/or
4// modify it under the terms of either
5//
6//   * the Apache License, Version 2.0 or
7//   * the MIT License
8//
9// at your option.
10//
11// You should have recieved copies of the Apache License and the MIT
12// License along with the library. If not, see
13// <https://www.apache.org/licenses/LICENSE-2.0> and
14// <https://opensource.org/licenses/MIT>.
15
16/*!
17# Numeric casts
18
19This crate provides casts and checked casts.
20
21## Quick examples
22
23```rust
24use az::{Az, OverflowingAs, WrappingAs};
25use core::num::Wrapping;
26
27// Panics on overflow with `debug_assertions`, otherwise wraps
28assert_eq!(12i32.az::<u32>(), 12u32);
29
30// Always wraps
31let wrapped = 1u32.wrapping_neg();
32assert_eq!((-1).wrapping_as::<u32>(), wrapped);
33assert_eq!((-1).overflowing_as::<u32>(), (wrapped, true));
34
35// Wrapping can also be obtained using `Wrapping`
36assert_eq!((-1).az::<Wrapping<u32>>().0, wrapped);
37```
38
39Conversions from floating-point to integers are also supported.
40Numbers are rounded towards zero, but the [`Round`] wrapper can be
41used to convert floating-point numbers to integers with rounding to
42the nearest, with ties rounded to even.
43
44```rust
45use az::{Az, CheckedAs, Round, SaturatingAs};
46use core::f32;
47
48assert_eq!(15.7.az::<i32>(), 15);
49assert_eq!(Round(15.5).az::<i32>(), 16);
50assert_eq!(1.5e20.saturating_as::<i32>(), i32::max_value());
51assert_eq!(f32::NAN.checked_as::<i32>(), None);
52```
53
54## Implementing casts for other types
55
56To provide casts for another type, you should implement the [`Cast`]
57trait and if necessary the [`CheckedCast`], [`SaturatingCast`],
58[`WrappingCast`], [`OverflowingCast`] and [`UnwrappedCast`] traits.
59The [`Az`], [`CheckedAs`], [`SaturatingAs`], [`WrappingAs`],
60[`OverflowingAs`] and [`UnwrappedAs`] traits are already implemented
61for all types using blanket implementations that make use of the
62former traits.
63
64The cast traits can also be implemented for references. This can be
65useful for expensive types that are not [`Copy`]. For example if you
66have your own integer type that does not implement [`Copy`], you could
67implement casts like in the following example. (The type `I` could be
68an expensive type, for example a bignum integer, but for the example
69it is only a wrapped [`i32`].)
70
71```rust
72use az::{Az, Cast};
73use core::borrow::Borrow;
74
75struct I(i32);
76impl Cast<i64> for &'_ I {
77    fn cast(self) -> i64 { self.0.cast() }
78}
79
80let owned = I(12);
81assert_eq!((&owned).az::<i64>(), 12);
82// borrow can be used if chaining is required
83assert_eq!(owned.borrow().az::<i64>(), 12);
84```
85
86## Using the *az* crate
87
88The *az* crate is available on [crates.io][*az* crate]. To use it in
89your crate, add it as a dependency inside [*Cargo.toml*]:
90
91```toml
92[dependencies]
93az = "1.2"
94```
95
96The crate requires rustc version 1.31.0 or later.
97
98## License
99
100This crate is free software: you can redistribute it and/or modify it
101under the terms of either
102
103  * the [Apache License, Version 2.0][LICENSE-APACHE] or
104  * the [MIT License][LICENSE-MIT]
105
106at your option.
107
108### Contribution
109
110Unless you explicitly state otherwise, any contribution intentionally
111submitted for inclusion in the work by you, as defined in the Apache
112License, Version 2.0, shall be dual licensed as above, without any
113additional terms or conditions.
114
115[*Cargo.toml*]: https://doc.rust-lang.org/cargo/guide/dependencies.html
116[*az* crate]: https://crates.io/crates/az
117[LICENSE-APACHE]: https://www.apache.org/licenses/LICENSE-2.0
118[LICENSE-MIT]: https://opensource.org/licenses/MIT
119*/
120#![no_std]
121#![warn(missing_docs)]
122#![doc(html_root_url = "https://docs.rs/az/~1.2")]
123#![doc(test(attr(deny(warnings))))]
124#![cfg_attr(feature = "fail-on-warnings", deny(warnings))]
125
126#[cfg(test)]
127extern crate std;
128
129mod float;
130mod int;
131#[cfg(test)]
132mod tests;
133
134/**
135Used to cast values.
136
137It is normally easier to use the [`Az`] trait instead of this trait.
138
139# Panics
140
141When debug assertions are enabled, this trait’s method panics if the
142value does not fit in the destination. When debug assertions are *not*
143enabled (usual in release mode), the wrapped value can be returned,
144but it is not considered a breaking change if in the future it panics;
145if wrapping is required use [`WrappingCast`] instead.
146
147This trait’s method also panics with no debug assertions if the value
148does not fit and cannot be wrapped, for example when trying to cast
149floating-point ∞ into an integer type.
150
151# Examples
152
153```rust
154use az::Cast;
155let a: u32 = 5i32.cast();
156assert_eq!(a, 5);
157assert_eq!(Cast::<u8>::cast(17.1f32), 17);
158```
159*/
160pub trait Cast<Dst> {
161    /// Casts the value.
162    fn cast(self) -> Dst;
163}
164
165/**
166Used for checked casts.
167
168This trait’s method returns [`None`] if the value does not fit.
169
170It is normally easier to use the [`CheckedAs`] trait instead of this trait.
171
172# Examples
173
174```rust
175use az::CheckedCast;
176use core::f32;
177
178let a: Option<u32> = 5i32.checked_cast();
179assert_eq!(a, Some(5));
180assert_eq!(CheckedCast::<u32>::checked_cast(-5i32), None);
181assert_eq!(CheckedCast::<u8>::checked_cast(17.1f32), Some(17));
182let b: Option<u8> = f32::NAN.checked_cast();
183assert_eq!(b, None);
184```
185*/
186pub trait CheckedCast<Dst> {
187    /// Casts the value.
188    fn checked_cast(self) -> Option<Dst>;
189}
190
191/**
192Used to cast into the destination type, saturating if the value does not fit.
193
194It is normally easier to use the [`SaturatingAs`] trait instead of this trait.
195
196# Panics
197
198This trait’s method panics if the value does not fit and saturation
199does not make sense, for example when trying to cast floating-point
200NaN into an integer type.
201
202# Examples
203
204```rust
205use az::SaturatingCast;
206let a: u32 = (-1).saturating_cast();
207assert_eq!(a, 0);
208assert_eq!(SaturatingCast::<u8>::saturating_cast(17.0 + 256.0), 255);
209```
210*/
211pub trait SaturatingCast<Dst> {
212    /// Casts the value.
213    fn saturating_cast(self) -> Dst;
214}
215
216/**
217Wrapping cast.
218
219It is normally easier to use the [`WrappingAs`] trait instead of this trait.
220
221# Panics
222
223This trait’s method panics if the value does not fit and cannot be
224wrapped, for example when trying to cast floating-point ∞ into an
225integer type.
226
227# Examples
228
229```rust
230use az::WrappingCast;
231let a: u32 = (-1).wrapping_cast();
232assert_eq!(a, u32::max_value());
233assert_eq!(WrappingCast::<u8>::wrapping_cast(17.0 + 256.0), 17);
234```
235*/
236pub trait WrappingCast<Dst> {
237    /// Casts the value.
238    fn wrapping_cast(self) -> Dst;
239}
240
241/**
242Used for overflowing casts.
243
244This trait’s method returns a [tuple] of the value and a [`bool`],
245indicating whether an overflow has occurred. On overflow, the wrapped
246value is returned.
247
248It is normally easier to use the [`OverflowingAs`] trait instead of this trait.
249
250# Examples
251
252```rust
253use az::OverflowingCast;
254let a: (u8, bool) = 17i32.overflowing_cast();
255assert_eq!(a, (17, false));
256assert_eq!(OverflowingCast::<u32>::overflowing_cast(-1), (u32::max_value(), true));
257assert_eq!(OverflowingCast::<u8>::overflowing_cast(17.0 + 256.0), (17, true));
258```
259
260# Panics
261
262This trait’s method panics if the value does not fit and cannot be
263wrapped, for example when trying to cast floating-point ∞ into an
264integer type.
265*/
266pub trait OverflowingCast<Dst> {
267    /// Casts the value.
268    fn overflowing_cast(self) -> (Dst, bool);
269}
270
271/**
272Used to cast values, panicking if the value does not fit.
273
274It is normally easier to use the [`UnwrappedAs`] trait instead of this trait.
275
276# Panics
277
278This trait’s method panics if the value does not fit in the
279destination, even when debug assertions are not enabled.
280
281# Examples
282
283```rust
284use az::UnwrappedCast;
285let a: u32 = 5i32.unwrapped_cast();
286assert_eq!(a, 5);
287assert_eq!(UnwrappedCast::<u8>::unwrapped_cast(17.1f32), 17);
288```
289
290The following panics because of overflow.
291
292```rust,should_panic
293use az::UnwrappedCast;
294let _overflow: u32 = (-5i32).unwrapped_cast();
295```
296*/
297pub trait UnwrappedCast<Dst> {
298    /// Casts the value.
299    #[cfg_attr(track_caller, track_caller)]
300    fn unwrapped_cast(self) -> Dst;
301}
302
303/**
304Used to cast values.
305
306This trait enables trait constraints for casting in the opposite direction to
307[`Cast`].
308
309# Examples
310
311```rust
312use az::CastFrom;
313trait Tr {
314    type Assoc: CastFrom<u8>;
315    fn assoc_from_u8(a: u8) -> Self::Assoc {
316        CastFrom::cast_from(a)
317    }
318}
319impl Tr for () {
320    type Assoc = i8;
321}
322assert_eq!(<() as Tr>::assoc_from_u8(5u8), 5i8);
323```
324*/
325pub trait CastFrom<Src> {
326    /// Casts the value.
327    fn cast_from(src: Src) -> Self;
328}
329
330impl<Src: Cast<Dst>, Dst> CastFrom<Src> for Dst {
331    #[inline]
332    #[cfg_attr(track_caller, track_caller)]
333    fn cast_from(src: Src) -> Self {
334        src.cast()
335    }
336}
337
338/**
339Used for checked casts.
340
341This trait enables trait constraints for casting in the opposite direction to
342[`CheckedCast`].
343
344# Examples
345
346```rust
347use az::CheckedCastFrom;
348trait Tr {
349    type Assoc: CheckedCastFrom<u8>;
350    fn checked_assoc_from_u8(a: u8) -> Option<Self::Assoc> {
351        CheckedCastFrom::checked_cast_from(a)
352    }
353}
354impl Tr for () {
355    type Assoc = i8;
356}
357assert_eq!(<() as Tr>::checked_assoc_from_u8(5u8), Some(5i8));
358assert_eq!(<() as Tr>::checked_assoc_from_u8(255u8), None);
359```
360*/
361pub trait CheckedCastFrom<Src>: Sized {
362    /// Casts the value.
363    fn checked_cast_from(src: Src) -> Option<Self>;
364}
365
366impl<Src: CheckedCast<Dst>, Dst> CheckedCastFrom<Src> for Dst {
367    #[inline]
368    #[cfg_attr(track_caller, track_caller)]
369    fn checked_cast_from(src: Src) -> Option<Self> {
370        src.checked_cast()
371    }
372}
373
374/**
375Used to cast, saturating if the value does not fit.
376
377This trait enables trait constraints for casting in the opposite direction to
378[`SaturatingCast`].
379
380# Examples
381
382```rust
383use az::SaturatingCastFrom;
384trait Tr {
385    type Assoc: SaturatingCastFrom<u8>;
386    fn saturating_assoc_from_u8(a: u8) -> Self::Assoc {
387        SaturatingCastFrom::saturating_cast_from(a)
388    }
389}
390impl Tr for () {
391    type Assoc = i8;
392}
393assert_eq!(<() as Tr>::saturating_assoc_from_u8(5u8), 5i8);
394assert_eq!(<() as Tr>::saturating_assoc_from_u8(255u8), 127i8);
395```
396*/
397pub trait SaturatingCastFrom<Src> {
398    /// Casts the value.
399    fn saturating_cast_from(src: Src) -> Self;
400}
401
402impl<Src: SaturatingCast<Dst>, Dst> SaturatingCastFrom<Src> for Dst {
403    #[inline]
404    #[cfg_attr(track_caller, track_caller)]
405    fn saturating_cast_from(src: Src) -> Self {
406        src.saturating_cast()
407    }
408}
409
410/**
411Wrapping cast.
412
413This trait enables trait constraints for casting in the opposite direction to
414[`WrappingCast`].
415
416# Examples
417
418```rust
419use az::WrappingCastFrom;
420trait Tr {
421    type Assoc: WrappingCastFrom<u8>;
422    fn wrapping_assoc_from_u8(a: u8) -> Self::Assoc {
423        WrappingCastFrom::wrapping_cast_from(a)
424    }
425}
426impl Tr for () {
427    type Assoc = i8;
428}
429assert_eq!(<() as Tr>::wrapping_assoc_from_u8(5u8), 5i8);
430assert_eq!(<() as Tr>::wrapping_assoc_from_u8(255u8), -1i8);
431```
432*/
433pub trait WrappingCastFrom<Src> {
434    /// Casts the value.
435    fn wrapping_cast_from(src: Src) -> Self;
436}
437
438impl<Src: WrappingCast<Dst>, Dst> WrappingCastFrom<Src> for Dst {
439    #[inline]
440    #[cfg_attr(track_caller, track_caller)]
441    fn wrapping_cast_from(src: Src) -> Self {
442        src.wrapping_cast()
443    }
444}
445
446/**
447Used for overflowing casts.
448
449This trait enables trait constraints for casting in the opposite direction to
450[`OverflowingCast`].
451
452# Examples
453
454```rust
455use az::OverflowingCastFrom;
456trait Tr {
457    type Assoc: OverflowingCastFrom<u8>;
458    fn overflowing_assoc_from_u8(a: u8) -> (Self::Assoc, bool) {
459        OverflowingCastFrom::overflowing_cast_from(a)
460    }
461}
462impl Tr for () {
463    type Assoc = i8;
464}
465assert_eq!(<() as Tr>::overflowing_assoc_from_u8(5u8), (5i8, false));
466assert_eq!(<() as Tr>::overflowing_assoc_from_u8(255u8), (-1i8, true));
467```
468*/
469pub trait OverflowingCastFrom<Src>: Sized {
470    /// Casts the value.
471    fn overflowing_cast_from(src: Src) -> (Self, bool);
472}
473
474impl<Src: OverflowingCast<Dst>, Dst> OverflowingCastFrom<Src> for Dst {
475    #[inline]
476    #[cfg_attr(track_caller, track_caller)]
477    fn overflowing_cast_from(src: Src) -> (Self, bool) {
478        src.overflowing_cast()
479    }
480}
481
482/**
483Used to cast values, panicking if the value does not fit.
484
485This trait enables trait constraints for casting in the opposite direction to
486[`UnwrappedCast`].
487
488# Examples
489
490```rust
491use az::UnwrappedCastFrom;
492trait Tr {
493    type Assoc: UnwrappedCastFrom<u8>;
494    fn unwrapped_assoc_from_u8(a: u8) -> Self::Assoc {
495        UnwrappedCastFrom::unwrapped_cast_from(a)
496    }
497}
498impl Tr for () {
499    type Assoc = i8;
500}
501assert_eq!(<() as Tr>::unwrapped_assoc_from_u8(5u8), 5i8);
502```
503
504The following assertion would panic because of overflow.
505
506```rust, should_panic
507# use az::UnwrappedCastFrom;
508# trait Tr {
509#     type Assoc: UnwrappedCastFrom<u8>;
510#     fn unwrapped_assoc_from_u8(a: u8) -> Self::Assoc {
511#         UnwrappedCastFrom::unwrapped_cast_from(a)
512#     }
513# }
514# impl Tr for () {
515#     type Assoc = i8;
516# }
517let _overflow = <() as Tr>::unwrapped_assoc_from_u8(255u8);
518```
519
520*/
521pub trait UnwrappedCastFrom<Src> {
522    /// Casts the value.
523    fn unwrapped_cast_from(src: Src) -> Self;
524}
525
526impl<Src: UnwrappedCast<Dst>, Dst> UnwrappedCastFrom<Src> for Dst {
527    #[inline]
528    #[cfg_attr(track_caller, track_caller)]
529    fn unwrapped_cast_from(src: Src) -> Self {
530        src.unwrapped_cast()
531    }
532}
533
534/**
535Used to cast values.
536
537This is a convenience trait to enable writing
538<code>src.[az][`Az::az`]::&lt;Dst&gt;()</code>. This would not work with
539the <code>[Cast][`Cast`]::[cast][`Cast::cast`]</code> method because
540the [`Cast`] trait is generic while its [`cast`][`Cast::cast`] method
541is not generic.
542
543This trait’s method is suitable for chaining.
544
545If there is an implementation of
546<code>[Cast][`Cast`]&lt;Dst&gt;</code> for `&Src` but not for `Src`,
547and the variable `src` is of type `Src`, then
548<code>src.[az][`Az::az`]::&lt;Dst&gt;()</code> would not work and
549<code>(&src).[az][`Az::az`]::&lt;Dst&gt;()</code> is not easy to use with
550chaining, but
551<code>src.[borrow][`borrow`]().[az][`Az::az`]::&lt;Dst&gt;()</code> works.
552
553# Panics
554
555When debug assertions are enabled, this trait’s method panics if the
556value does not fit in the destination. When debug assertions are *not*
557enabled (usual in release mode), the wrapped value can be returned,
558but it is not considered a breaking change if in the future it panics;
559if wrapping is required use [`WrappingAs`] instead.
560
561This trait’s method also panics with no debug assertions if the value
562does not fit and cannot be wrapped, for example when trying to cast
563floating-point ∞ into an integer type.
564
565# Examples
566
567```rust
568use az::Az;
569assert_eq!(5i32.az::<u32>(), 5);
570assert_eq!(17.1f32.az::<u8>(), 17);
571```
572
573The following example shows how this trait can be used when [`Cast`]
574is implemented for a reference type.
575
576```rust
577use az::{Az, Cast};
578use core::borrow::Borrow;
579struct I(i32);
580impl Cast<i64> for &'_ I {
581    fn cast(self) -> i64 { self.0.cast() }
582}
583
584let r = &I(-5);
585assert_eq!(r.az::<i64>(), -5);
586let owned = I(12);
587assert_eq!(owned.borrow().az::<i64>(), 12);
588```
589
590[`borrow`]: `core::borrow::Borrow::borrow`
591*/
592pub trait Az {
593    /// Casts the value.
594    fn az<Dst>(self) -> Dst
595    where
596        Self: Cast<Dst>;
597}
598
599impl<T> Az for T {
600    #[inline]
601    #[cfg_attr(track_caller, track_caller)]
602    fn az<Dst>(self) -> Dst
603    where
604        Self: Cast<Dst>,
605    {
606        self.cast()
607    }
608}
609
610/**
611Used for checked casts.
612
613This trait’s method returns [`None`] if the value does not fit.
614
615This is a convenience trait to enable writing
616<code>src.[checked\_as][`CheckedAs::checked_as`]::&lt;Dst&gt;()</code>. This
617would not work with the
618<code>[CheckedCast][`CheckedCast`]::[checked\_cast][`CheckedCast::checked_cast`]</code>
619method because the [`CheckedCast`] trait is generic while its
620[`checked_cast`][`CheckedCast::checked_cast`] method is not generic.
621
622This trait’s method is suitable for chaining.
623
624If there is an implementation of
625<code>[CheckedCast][`CheckedCast`]&lt;Dst&gt;</code> for `&Src` but
626not for `Src`, and the variable `src` is of type `Src`, then
627<code>src.[checked\_as][`CheckedAs::checked_as`]::&lt;Dst&gt;()</code> would not
628work and
629<code>(&src).[checked\_as][`CheckedAs::checked_as`]::&lt;Dst&gt;()</code> is not
630easy to use with chaining, but
631<code>src.[borrow][`borrow`]().[checked\_as][`CheckedAs::checked_as`]::&lt;Dst&gt;()</code>
632works.
633
634# Examples
635
636```rust
637use az::CheckedAs;
638use core::f32;
639
640assert_eq!(5i32.checked_as::<u32>(), Some(5));
641assert_eq!((-5i32).checked_as::<u32>(), None);
642assert_eq!(17.1f32.checked_as::<u8>(), Some(17));
643assert_eq!(f32::NAN.checked_as::<u8>(), None);
644```
645
646The following example shows how this trait can be used when
647[`CheckedCast`] is implemented for a reference type.
648
649```rust
650use az::{CheckedAs, CheckedCast};
651use core::borrow::Borrow;
652struct I(i32);
653impl CheckedCast<u32> for &'_ I {
654    fn checked_cast(self) -> Option<u32> { self.0.checked_cast() }
655}
656
657let r = &I(-5);
658assert_eq!(r.checked_as::<u32>(), None);
659let owned = I(12);
660assert_eq!(owned.borrow().checked_as::<u32>(), Some(12));
661```
662
663[`borrow`]: `core::borrow::Borrow::borrow`
664*/
665pub trait CheckedAs {
666    /// Casts the value.
667    fn checked_as<Dst>(self) -> Option<Dst>
668    where
669        Self: CheckedCast<Dst>;
670}
671
672impl<T> CheckedAs for T {
673    #[inline]
674    #[cfg_attr(track_caller, track_caller)]
675    fn checked_as<Dst>(self) -> Option<Dst>
676    where
677        Self: CheckedCast<Dst>,
678    {
679        self.checked_cast()
680    }
681}
682
683/**
684Used to cast into the destination type, saturating if the value does not fit.
685
686This is a convenience trait to enable writing
687<code>src.[saturating\_as][`SaturatingAs::saturating_as`]::&lt;Dst&gt;()</code>.
688This would not work with the
689<code>[SaturatingCast][`SaturatingCast`]::[saturating\_cast][`SaturatingCast::saturating_cast`]</code>
690method because the [`SaturatingCast`] trait is generic while its
691[`SaturatingCast::saturating_cast`] method is not generic.
692
693This trait’s method is suitable for chaining.
694
695If there is an implementation of
696<code>[SaturatingCast][`SaturatingCast`]&lt;Dst&gt;</code> for `&Src`
697but not for `Src`, and the variable `src` is of type `Src`, then
698<code>src.[saturating\_as][`SaturatingAs::saturating_as`]::&lt;Dst&gt;()</code>
699would not work and
700<code>(&src).[saturating\_as][`SaturatingAs::saturating_as`]::&lt;Dst&gt;()</code>
701is not easy to use with chaining, but
702<code>src.[borrow][`borrow`]().[saturating\_as][`SaturatingAs::saturating_as`]::&lt;Dst&gt;()</code>
703works.
704
705# Panics
706
707This trait’s method panics if the value does not fit and saturation
708does not make sense, for example when trying to cast floating-point
709NaN into an integer type.
710
711# Examples
712
713```rust
714use az::SaturatingAs;
715assert_eq!((-1).saturating_as::<u32>(), 0);
716assert_eq!((17.0 + 256.0).saturating_as::<u8>(), 255);
717```
718
719The following example shows how this trait can be used when
720[`SaturatingCast`] is implemented for a reference type.
721
722```rust
723use az::{SaturatingAs, SaturatingCast};
724use core::borrow::Borrow;
725struct I(i32);
726impl SaturatingCast<u32> for &'_ I {
727    fn saturating_cast(self) -> u32 { self.0.saturating_cast() }
728}
729
730let r = &I(-5);
731assert_eq!(r.saturating_as::<u32>(), 0);
732let owned = I(12);
733assert_eq!(owned.borrow().saturating_as::<u32>(), 12);
734```
735
736[`borrow`]: `core::borrow::Borrow::borrow`
737*/
738pub trait SaturatingAs {
739    /// Casts the value.
740    fn saturating_as<Dst>(self) -> Dst
741    where
742        Self: SaturatingCast<Dst>;
743}
744
745impl<T> SaturatingAs for T {
746    #[inline]
747    #[cfg_attr(track_caller, track_caller)]
748    fn saturating_as<Dst>(self) -> Dst
749    where
750        Self: SaturatingCast<Dst>,
751    {
752        self.saturating_cast()
753    }
754}
755
756/**
757Wrapping cast.
758
759This is a convenience trait to enable writing
760<code>src.[wrapping\_as][`WrappingAs::wrapping_as`]::&lt;Dst&gt;()</code>. This
761would not work with the
762<code>[WrappingCast][`WrappingCast`]::[wrapping\_cast][`WrappingCast::wrapping_cast`]</code>
763method because the [`WrappingCast`] trait is generic while its
764[`WrappingCast::wrapping_cast`] method is not generic.
765
766This trait’s method is suitable for chaining.
767
768If there is an implementation of
769<code>[WrappingCast][`WrappingCast`]&lt;Dst&gt;</code> for `&Src` but
770not for `Src`, and the variable `src` is of type `Src`, then
771<code>src.[wrapping\_as][`WrappingAs::wrapping_as`]::&lt;Dst&gt;()</code> would
772not work and
773<code>(&src).[wrapping\_as][`WrappingAs::wrapping_as`]::&lt;Dst&gt;()</code> is
774not easy to use with chaining, but
775<code>src.[borrow][`borrow`]().[wrapping\_as][`WrappingAs::wrapping_as`]::&lt;Dst&gt;()</code>
776works.
777
778# Panics
779
780This trait’s method panics if the value does not fit and cannot be
781wrapped, for example when trying to cast floating-point ∞ into an
782integer type.
783
784# Examples
785
786```rust
787use az::WrappingAs;
788assert_eq!((-1).wrapping_as::<u32>(), u32::max_value());
789assert_eq!((17.0 + 256.0).wrapping_as::<u8>(), 17);
790```
791
792The following example shows how this trait can be used when
793[`WrappingCast`] is implemented for a reference type.
794
795```rust
796use az::{WrappingAs, WrappingCast};
797use core::borrow::Borrow;
798struct I(i32);
799impl WrappingCast<u32> for &'_ I {
800    fn wrapping_cast(self) -> u32 { self.0.wrapping_cast() }
801}
802
803let r = &I(-5);
804assert_eq!(r.wrapping_as::<u32>(), 5u32.wrapping_neg());
805let owned = I(12);
806assert_eq!(owned.borrow().wrapping_as::<u32>(), 12);
807```
808
809[`borrow`]: `core::borrow::Borrow::borrow`
810*/
811pub trait WrappingAs {
812    /// Casts the value.
813    fn wrapping_as<Dst>(self) -> Dst
814    where
815        Self: WrappingCast<Dst>;
816}
817
818impl<T> WrappingAs for T {
819    #[inline]
820    #[cfg_attr(track_caller, track_caller)]
821    fn wrapping_as<Dst>(self) -> Dst
822    where
823        Self: WrappingCast<Dst>,
824    {
825        self.wrapping_cast()
826    }
827}
828
829/**
830Used for overflowing casts.
831
832This trait’s method returns a [tuple] of the value and a [`bool`],
833indicating whether an overflow has occurred. On overflow, the wrapped
834value is returned.
835
836This is a convenience trait to enable writing
837<code>src.[overflowing\_as][`OverflowingAs::overflowing_as`]::&lt;Dst&gt;()</code>.
838This would not work with the
839<code>[OverflowingCast][`OverflowingCast`]::[overflowing\_cast][`OverflowingCast::overflowing_cast`]</code>
840method because the [`OverflowingCast`] trait is generic while its
841[`OverflowingCast::overflowing_cast`] method is not generic.
842
843This trait’s method is suitable for chaining.
844
845If there is an implementation of
846<code>[OverflowingCast][`OverflowingCast`]&lt;Dst&gt;</code> for
847`&Src` but not for `Src`, and the variable `src` is of type `Src`,
848then
849<code>src.[overflowing\_as][`OverflowingAs::overflowing_as`]::&lt;Dst&gt;()</code>
850would not work and
851<code>(&src).[overflowing\_as][`OverflowingAs::overflowing_as`]::&lt;Dst&gt;()</code>
852is not easy to use with chaining, but
853<code>src.[borrow][`borrow`]().[overflowing\_as][`OverflowingAs::overflowing_as`]::&lt;Dst&gt;()</code>
854works.
855
856# Panics
857
858This trait’s method panics if the value does not fit and cannot be
859wrapped, for example when trying to cast floating-point ∞ into an
860integer type.
861
862# Examples
863
864```rust
865use az::OverflowingAs;
866assert_eq!(17i32.overflowing_as::<u8>(), (17, false));
867assert_eq!((-1).overflowing_as::<u32>(), (u32::max_value(), true));
868assert_eq!((17.0 + 256.0).overflowing_as::<u8>(), (17, true));
869```
870
871The following example shows how this trait can be used when
872[`OverflowingCast`] is implemented for a reference type.
873
874```rust
875use az::{OverflowingAs, OverflowingCast};
876use core::borrow::Borrow;
877struct I(i32);
878impl OverflowingCast<u32> for &'_ I {
879    fn overflowing_cast(self) -> (u32, bool) { self.0.overflowing_cast() }
880}
881
882let r = &I(-5);
883assert_eq!(r.overflowing_as::<u32>(), (5u32.wrapping_neg(), true));
884let owned = I(12);
885assert_eq!(owned.borrow().overflowing_as::<u32>(), (12, false));
886```
887
888[`borrow`]: `core::borrow::Borrow::borrow`
889*/
890pub trait OverflowingAs {
891    /// Casts the value.
892    fn overflowing_as<Dst>(self) -> (Dst, bool)
893    where
894        Self: OverflowingCast<Dst>;
895}
896
897impl<T> OverflowingAs for T {
898    #[inline]
899    #[cfg_attr(track_caller, track_caller)]
900    fn overflowing_as<Dst>(self) -> (Dst, bool)
901    where
902        Self: OverflowingCast<Dst>,
903    {
904        self.overflowing_cast()
905    }
906}
907
908/**
909Used to cast values, panicking if the value does not fit.
910
911This is a convenience trait to enable writing
912<code>src.[unwrapped\_as][`UnwrappedAs::unwrapped_as`]::&lt;Dst&gt;()</code>.
913This would not work with the
914<code>[UnwrappedCast][`UnwrappedCast`]::[unwrapped\_cast][`UnwrappedCast::unwrapped_cast`]</code>
915method because the [`UnwrappedCast`] trait is generic while its
916[`UnwrappedCast::unwrapped_cast`] method is not generic.
917
918This trait’s method is suitable for chaining.
919
920If there is an implementation of
921<code>[UnwrappedCast][`UnwrappedCast`]&lt;Dst&gt;</code> for `&Src`
922but not for `Src`, and the variable `src` is of type `Src`, then
923<code>src.[unwrapped\_as][`UnwrappedAs::unwrapped_as`]::&lt;Dst&gt;()</code>
924would not work and
925<code>(&src).[unwrapped\_as][`UnwrappedAs::unwrapped_as`]::&lt;Dst&gt;()</code>
926is not easy to use with chaining, but
927<code>src.[borrow][`borrow`]().[unwrapped\_as][`UnwrappedAs::unwrapped_as`]::&lt;Dst&gt;()</code>
928works.
929
930# Panics
931
932This trait’s method panics if the value does not fit in the
933destination, even when debug assertions are not enabled.
934
935# Examples
936
937```rust
938use az::UnwrappedAs;
939assert_eq!(5i32.unwrapped_as::<u32>(), 5);
940assert_eq!(17.1f32.unwrapped_as::<u8>(), 17);
941```
942
943The following panics because of overflow.
944
945```rust,should_panic
946use az::UnwrappedAs;
947let _overflow = (-5i32).unwrapped_as::<u32>();
948```
949
950The following example shows how this trait can be used when
951[`UnwrappedCast`] is implemented for a reference type.
952
953```rust
954use az::{UnwrappedAs, UnwrappedCast};
955use core::borrow::Borrow;
956struct I(i32);
957impl UnwrappedCast<i64> for &'_ I {
958    fn unwrapped_cast(self) -> i64 { self.0.unwrapped_cast() }
959}
960
961let r = &I(-5);
962assert_eq!(r.unwrapped_as::<i64>(), -5);
963let owned = I(12);
964assert_eq!(owned.borrow().unwrapped_as::<i64>(), 12);
965```
966
967[`borrow`]: `core::borrow::Borrow::borrow`
968*/
969pub trait UnwrappedAs {
970    /// Casts the value.
971    #[cfg_attr(track_caller, track_caller)]
972    fn unwrapped_as<Dst>(self) -> Dst
973    where
974        Self: UnwrappedCast<Dst>;
975}
976
977impl<T> UnwrappedAs for T {
978    #[inline]
979    fn unwrapped_as<Dst>(self) -> Dst
980    where
981        Self: UnwrappedCast<Dst>,
982    {
983        self.unwrapped_cast()
984    }
985}
986
987/// Casts the value.
988///
989/// # Panics
990///
991/// When debug assertions are enabled, panics if the value does not
992/// fit in the destination. When debug assertions are *not* enabled
993/// (usual in release mode), the wrapped value can be returned, but it
994/// is not considered a breaking change if in the future it panics; if
995/// wrapping is required use [`wrapping_cast`] instead.
996///
997/// This function also panics with no debug assertions if the value
998/// does not fit and cannot be wrapped, for example when trying to
999/// cast floating-point ∞ into an integer type.
1000///
1001/// # Examples
1002///
1003/// ```rust
1004/// assert_eq!(az::cast::<i32, u32>(5), 5);
1005/// assert_eq!(az::cast::<f32, u8>(17.1), 17);
1006/// ```
1007#[inline]
1008#[cfg_attr(track_caller, track_caller)]
1009pub fn cast<Src: Cast<Dst>, Dst>(src: Src) -> Dst {
1010    src.cast()
1011}
1012
1013/// Casts the value, returning [`None`] if the value does not fit.
1014///
1015/// # Examples
1016///
1017/// ```rust
1018/// use core::f32;
1019///
1020/// assert_eq!(az::checked_cast::<i32, u32>(5), Some(5));
1021/// assert_eq!(az::checked_cast::<i32, u32>(-5), None);
1022/// assert_eq!(az::checked_cast::<f32, u8>(17.1), Some(17));
1023/// assert_eq!(az::checked_cast::<f32, u8>(f32::NAN), None);
1024/// ```
1025#[inline]
1026#[cfg_attr(track_caller, track_caller)]
1027pub fn checked_cast<Src: CheckedCast<Dst>, Dst>(src: Src) -> Option<Dst> {
1028    src.checked_cast()
1029}
1030
1031/// Casts the value, saturating if the value does not fit.
1032///
1033/// # Panics
1034///
1035/// Panics if the value does not fit and saturation does not make
1036/// sense, for example when trying to cast floating-point NaN into an
1037/// integer type.
1038///
1039/// # Examples
1040///
1041/// ```rust
1042/// assert_eq!(az::saturating_cast::<i32, u32>(-1), 0);
1043/// assert_eq!(az::saturating_cast::<f32, u8>(17.0 + 256.0), 255);
1044/// ```
1045#[inline]
1046#[cfg_attr(track_caller, track_caller)]
1047pub fn saturating_cast<Src: SaturatingCast<Dst>, Dst>(src: Src) -> Dst {
1048    src.saturating_cast()
1049}
1050
1051/// Casts the value, wrapping on overflow.
1052///
1053/// # Panics
1054///
1055/// Panics if the value does not fit and cannot be wrapped, for
1056/// example when trying to cast floating-point ∞ into an integer type.
1057///
1058/// # Examples
1059///
1060/// ```rust
1061/// assert_eq!(az::wrapping_cast::<i32, u32>(-1), u32::max_value());
1062/// assert_eq!(az::wrapping_cast::<f32, u8>(17.0 + 256.0), 17);
1063/// ```
1064#[inline]
1065#[cfg_attr(track_caller, track_caller)]
1066pub fn wrapping_cast<Src: WrappingCast<Dst>, Dst>(src: Src) -> Dst {
1067    src.wrapping_cast()
1068}
1069
1070/// Overflowing cast.
1071///
1072/// Returns a [tuple] of the value and a [`bool`], indicating whether
1073/// an overflow has occurred. On overflow, the wrapped value is
1074/// returned.
1075///
1076/// # Panics
1077///
1078/// Panics if the value does not fit and cannot be wrapped, for
1079/// example when trying to cast floating-point ∞ into an integer type.
1080///
1081/// # Examples
1082///
1083/// ```rust
1084/// assert_eq!(az::overflowing_cast::<i32, u32>(-1), (u32::max_value(), true));
1085/// assert_eq!(az::overflowing_cast::<f32, u8>(17.0 + 256.0), (17, true));
1086/// ```
1087#[inline]
1088#[cfg_attr(track_caller, track_caller)]
1089pub fn overflowing_cast<Src: OverflowingCast<Dst>, Dst>(src: Src) -> (Dst, bool) {
1090    src.overflowing_cast()
1091}
1092
1093/// Casts the value, panicking if the value does not fit.
1094///
1095/// # Panics
1096///
1097/// Panics if the value does not fit in the destination, even when
1098/// debug assertions are not enabled.
1099///
1100/// # Examples
1101///
1102/// ```rust
1103/// assert_eq!(az::unwrapped_cast::<i32, u32>(5), 5);
1104/// assert_eq!(az::unwrapped_cast::<f32, u8>(17.1), 17);
1105/// ```
1106///
1107/// The following panics because of overflow.
1108///
1109/// ```rust,should_panic
1110/// let _overflow = az::unwrapped_cast::<i32, u32>(-5);
1111/// ```
1112#[inline]
1113#[cfg_attr(track_caller, track_caller)]
1114pub fn unwrapped_cast<Src: UnwrappedCast<Dst>, Dst>(src: Src) -> Dst {
1115    src.unwrapped_cast()
1116}
1117
1118/// Used to convert floating-point numbers to integers with rounding
1119/// to the nearest, with ties rounded to even.
1120///
1121/// The underlying value can be retrieved through the `.0` index.
1122///
1123/// # Examples
1124///
1125/// ```rust
1126/// use az::Round;
1127/// assert_eq!(az::cast::<_, i32>(Round(0.4)), 0);
1128/// assert_eq!(az::cast::<_, i32>(Round(0.6)), 1);
1129/// // ties rounded to even
1130/// assert_eq!(az::cast::<_, i32>(Round(-0.5)), 0);
1131/// assert_eq!(az::cast::<_, i32>(Round(-1.5)), -2);
1132/// ```
1133#[repr(transparent)]
1134#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
1135pub struct Round<T>(pub T);