qrcode_core/cast.rs
1//! Checked narrowing conversions and truncation helpers used across the encoder.
2
3/// Truncate a value to u8 by masking the lower 8 bits.
4pub trait Truncate {
5 /// Truncates this value to its low 8 bits as a `u8`.
6 fn truncate_as_u8(self) -> u8;
7}
8
9impl Truncate for u16 {
10 #[allow(clippy::cast_possible_truncation)]
11 fn truncate_as_u8(self) -> u8 {
12 (self & 0xff) as u8
13 }
14}
15
16/// Checked narrowing conversions with debug-mode overflow assertions.
17///
18/// In debug builds, these use `TryFrom` + `unwrap()` to catch overflow bugs.
19/// In release builds, they compile to plain `as` casts (zero cost).
20///
21/// Standard traits can't replace this: `From` only supports lossless widening,
22/// `TryFrom` returns `Result` which would require changing all call sites.
23#[allow(clippy::wrong_self_convention)]
24pub trait As {
25 /// Narrows to `u16` (panics on overflow in debug, `as` in release).
26 fn as_u16(self) -> u16;
27 /// Narrows to `i16` (panics on overflow in debug, `as` in release).
28 fn as_i16(self) -> i16;
29 /// Widens/narrows to `u32` (panics on overflow in debug, `as` in release).
30 fn as_u32(self) -> u32;
31 /// Widens/narrows to `usize` (panics on overflow in debug, `as` in release).
32 fn as_usize(self) -> usize;
33 /// Widens/narrows to `isize` (panics on overflow in debug, `as` in release).
34 fn as_isize(self) -> isize;
35}
36
37macro_rules! impl_as {
38 ($ty:ty) => {
39 #[cfg(debug_assertions)]
40 impl As for $ty {
41 fn as_u16(self) -> u16 {
42 u16::try_from(self).unwrap()
43 }
44
45 fn as_i16(self) -> i16 {
46 i16::try_from(self).unwrap()
47 }
48
49 fn as_u32(self) -> u32 {
50 u32::try_from(self).unwrap()
51 }
52
53 fn as_usize(self) -> usize {
54 usize::try_from(self).unwrap()
55 }
56
57 fn as_isize(self) -> isize {
58 isize::try_from(self).unwrap()
59 }
60 }
61
62 #[cfg(not(debug_assertions))]
63 impl As for $ty {
64 fn as_u16(self) -> u16 {
65 self as u16
66 }
67 fn as_i16(self) -> i16 {
68 self as i16
69 }
70 fn as_u32(self) -> u32 {
71 self as u32
72 }
73 fn as_usize(self) -> usize {
74 self as usize
75 }
76 fn as_isize(self) -> isize {
77 self as isize
78 }
79 }
80 };
81}
82
83impl_as!(i16);
84impl_as!(u32);
85impl_as!(usize);
86impl_as!(isize);