az/
lib.rs

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