windows_helpers/
bit_manipulation.rs

1use crate::windows;
2use std::{mem, ops::BitOrAssign};
3use windows::Win32::Foundation::{LPARAM, LRESULT, WPARAM};
4
5#[inline]
6pub fn build_bit_flag_set<I, T>(flag_translations: I) -> T
7where
8    I: IntoIterator<Item = (bool, T)>,
9    T: Default + BitOrAssign,
10{
11    //! Translates booleans to bits in a bit set.
12
13    let mut bit_flag_set = T::default();
14
15    for (needed, flag_bit_mask) in flag_translations.into_iter() {
16        if needed {
17            bit_flag_set |= flag_bit_mask;
18        }
19    }
20
21    bit_flag_set
22}
23
24/// A trait concerned with the least significant 16 bits of integer types.
25pub trait Width16BitPortion
26where
27    Self: Sized,
28{
29    fn from_low_high_u8(low: u8, high: u8) -> Self;
30
31    #[inline]
32    fn from_high_low_u8(high: u8, low: u8) -> Self {
33        Self::from_low_high_u8(low, high)
34    }
35
36    fn low_u8(self) -> u8;
37    fn high_u8(self) -> u8;
38}
39
40macro_rules! impl_width_16_portion {
41    ($($type:ty),*) => {
42        $(
43            impl Width16BitPortion for $type {
44                #[inline]
45                fn from_low_high_u8(low: u8, high: u8) -> Self {
46                    ((low as u16 & 0xff) | ((high as u16 & 0xff) << 8)) as Self
47                }
48
49                #[inline]
50                fn low_u8(self) -> u8 {
51                    (self & 0xff) as u8
52                }
53
54                #[inline]
55                fn high_u8(self) -> u8 {
56                    (self >> 8 & 0xff) as u8
57                }
58            }
59        )*
60    };
61}
62
63impl_width_16_portion!(u16, i16);
64
65/// A trait concerned with the least significant 32 bits of integer types.
66pub trait Width32BitPortion
67where
68    Self: Sized,
69{
70    fn from_low_high_u16(low: u16, high: u16) -> Self;
71
72    #[inline]
73    fn from_high_low_u16(high: u16, low: u16) -> Self {
74        Self::from_low_high_u16(low, high)
75    }
76
77    #[inline]
78    fn from_low_high_i16(low: i16, high: i16) -> Self {
79        Self::from_low_high_u16(low as u16, high as u16)
80    }
81
82    #[inline]
83    fn from_high_low_i16(high: i16, low: i16) -> Self {
84        Self::from_low_high_i16(low, high)
85    }
86
87    fn low_u16(self) -> u16;
88    fn high_u16(self) -> u16;
89
90    #[inline]
91    fn low_i16(self) -> i16 {
92        self.low_u16() as i16
93    }
94
95    #[inline]
96    fn high_i16(self) -> i16 {
97        self.high_u16() as i16
98    }
99}
100
101macro_rules! impl_width_32_portion {
102    ($($type:ty),*) => {
103        $(
104            impl Width32BitPortion for $type {
105                #[inline]
106                fn from_low_high_u16(low: u16, high: u16) -> Self {
107                    ((low as u32 & 0xffff) | ((high as u32 & 0xffff) << 16)) as Self
108                }
109
110                #[inline]
111                fn low_u16(self) -> u16 {
112                    (self & 0xffff) as u16
113                }
114
115                #[inline]
116                fn high_u16(self) -> u16 {
117                    (self >> 16 & 0xffff) as u16
118                }
119            }
120        )*
121    };
122}
123
124impl_width_32_portion!(u32, i32, usize, isize);
125
126macro_rules! impl_width_32_portion_for_ptr_sized_1_tuple {
127    ($($type:ty),*) => {
128        $(
129            impl Width32BitPortion for $type {
130                #[inline]
131                fn from_low_high_u16(low: u16, high: u16) -> Self {
132                    unsafe { mem::transmute(usize::from_low_high_u16(low, high)) }
133                }
134
135                #[inline]
136                fn low_u16(self) -> u16 {
137                    self.0.low_u16()
138                }
139
140                #[inline]
141                fn high_u16(self) -> u16 {
142                    self.0.high_u16()
143                }
144            }
145        )*
146    };
147}
148
149#[cfg(feature = "f_Win32_Foundation")]
150impl_width_32_portion_for_ptr_sized_1_tuple!(WPARAM, LPARAM, LRESULT);