wgpu_types/
bitflags_array.rs1macro_rules! bitflags_array_impl {
2 ($impl_name:ident $inner_name:ident $name:ident $op:tt $($struct_names:ident)*) => (
3 impl core::ops::$impl_name for $name {
4 type Output = Self;
5
6 #[inline]
7 fn $inner_name(self, other: Self) -> Self {
8 Self {
9 $($struct_names: self.$struct_names $op other.$struct_names,)*
10 }
11 }
12 }
13 )
14 }
15pub(crate) use bitflags_array_impl;
16
17macro_rules! bitflags_array_impl_assign {
18 ($impl_name:ident $inner_name:ident $name:ident $op:tt $($struct_names:ident)*) => (
19 impl core::ops::$impl_name for $name {
20 #[inline]
21 fn $inner_name(&mut self, other: Self) {
22 $(self.$struct_names $op other.$struct_names;)*
23 }
24 }
25 )
26 }
27pub(crate) use bitflags_array_impl_assign;
28
29macro_rules! bit_array_impl {
30 ($impl_name:ident $inner_name:ident $name:ident $op:tt) => (
31 impl core::ops::$impl_name for $name {
32 type Output = Self;
33
34 #[inline]
35 fn $inner_name(mut self, other: Self) -> Self {
36 for (inner, other) in self.0.iter_mut().zip(other.0.iter()) {
37 *inner $op *other;
38 }
39 self
40 }
41 }
42 )
43 }
44pub(crate) use bit_array_impl;
45
46macro_rules! bitflags_independent_two_arg {
47 ($(#[$meta:meta])* $func_name:ident $($struct_names:ident)*) => (
48 $(#[$meta])*
49 pub const fn $func_name(self, other:Self) -> Self {
50 Self { $($struct_names: self.$struct_names.$func_name(other.$struct_names),)* }
51 }
52 )
53 }
54pub(crate) use bitflags_independent_two_arg;
55
56macro_rules! bitflags_array {
63 (
64 $(#[$outer:meta])*
65 pub struct ($name:ident, $name_bits:ident): [$T:ty; $Len:expr];
66
67 $(
68 $(#[$bit_outer:meta])*
69 $vis:vis struct $inner_name:ident $lower_inner_name:ident {
70 $(
71 $(#[doc $($args:tt)*])*
72 const $Flag:tt = $value:expr;
73 )*
74 }
75 )*
76 ) => {
77 $(
78 bitflags::bitflags! {
79 $(#[$bit_outer])*
80 $vis struct $inner_name: $T {
81 $(
82 $(#[doc $($args)*])*
83 const $Flag = $value;
84 )*
85 }
86 }
87 )*
88
89 $(#[$outer])*
90 pub struct $name {
91 $(
92 #[allow(missing_docs)]
93 $vis $lower_inner_name: $inner_name,
94 )*
95 }
96
97 #[doc = concat!("Bits from [`", stringify!($name), "`] in array form")]
98 #[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
99 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
100 pub struct $name_bits(pub [$T; $Len]);
101
102 $crate::bitflags_array_impl! { BitOr bitor $name | $($lower_inner_name)* }
103 $crate::bitflags_array_impl! { BitAnd bitand $name & $($lower_inner_name)* }
104 $crate::bitflags_array_impl! { BitXor bitxor $name ^ $($lower_inner_name)* }
105 impl core::ops::Not for $name {
106 type Output = Self;
107
108 #[inline]
109 fn not(self) -> Self {
110 Self {
111 $($lower_inner_name: !self.$lower_inner_name,)*
112 }
113 }
114 }
115 $crate::bitflags_array_impl! { Sub sub $name - $($lower_inner_name)* }
116
117 #[cfg(feature = "serde")]
118 impl Serialize for $name {
119 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
120 where
121 S: serde::Serializer,
122 {
123 bitflags::serde::serialize(self, serializer)
124 }
125 }
126
127 #[cfg(feature = "serde")]
128 impl<'de> Deserialize<'de> for $name {
129 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
130 where
131 D: serde::Deserializer<'de>,
132 {
133 bitflags::serde::deserialize(deserializer)
134 }
135 }
136
137 impl core::fmt::Display for $name {
138 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
139 let mut iter = self.iter_names();
140 let mut next = iter.next();
142 while let Some((name, _)) = next {
143 f.write_str(name)?;
144 next = iter.next();
145 if next.is_some() {
146 f.write_str(" | ")?;
147 }
148 }
149 Ok(())
150 }
151 }
152
153 $crate::bitflags_array_impl_assign! { BitOrAssign bitor_assign $name |= $($lower_inner_name)* }
154 $crate::bitflags_array_impl_assign! { BitAndAssign bitand_assign $name &= $($lower_inner_name)* }
155 $crate::bitflags_array_impl_assign! { BitXorAssign bitxor_assign $name ^= $($lower_inner_name)* }
156
157 $crate::bit_array_impl! { BitOr bitor $name_bits |= }
158 $crate::bit_array_impl! { BitAnd bitand $name_bits &= }
159 $crate::bit_array_impl! { BitXor bitxor $name_bits ^= }
160
161 impl core::ops::Not for $name_bits {
162 type Output = Self;
163
164 #[inline]
165 fn not(self) -> Self {
166 let [$($lower_inner_name,)*] = self.0;
167 Self([$(!$lower_inner_name,)*])
168 }
169 }
170
171 #[cfg(feature = "serde")]
172 impl bitflags::parser::WriteHex for $name_bits {
173 fn write_hex<W: core::fmt::Write>(&self, mut writer: W) -> core::fmt::Result {
174 let [$($lower_inner_name,)*] = self.0;
175 let mut wrote = false;
176 let mut stager = alloc::string::String::with_capacity(size_of::<$T>() * 2);
177 $(if ($lower_inner_name != 0) || wrote {
181 $lower_inner_name.write_hex(&mut stager)?;
185 if (stager.len() != size_of::<$T>() * 2) && wrote {
186 let zeros_to_write = (size_of::<$T>() * 2) - stager.len();
187 for _ in 0..zeros_to_write {
188 writer.write_char('0')?
189 }
190 }
191 writer.write_str(&stager)?;
192 stager.clear();
193 wrote = true;
194 })*
195 if !wrote {
196 writer.write_str("0")?;
197 }
198 Ok(())
199 }
200 }
201
202 #[cfg(feature = "serde")]
203 impl bitflags::parser::ParseHex for $name_bits {
204 fn parse_hex(input: &str) -> Result<Self, bitflags::parser::ParseError> {
205 use bitflags::Bits;
206
207 let mut unset = Self::EMPTY;
208 let mut end = input.len();
209 if end == 0 {
210 return Err(bitflags::parser::ParseError::empty_flag())
211 }
212 for (idx, _) in [$(stringify!($lower_inner_name),)*].iter().enumerate().rev() {
214 let checked_start = end.checked_sub(size_of::<$T>() * 2);
216 let start = checked_start.unwrap_or(0);
217
218 let cur_input = &input[start..end];
219 unset.0[idx] = <$T>::from_str_radix(cur_input, 16)
220 .map_err(|_|bitflags::parser::ParseError::invalid_hex_flag(cur_input))?;
221
222 end = start;
223
224 if let None = checked_start {
225 break;
226 }
227 }
228 Ok(unset)
229 }
230 }
231
232 impl bitflags::Bits for $name_bits {
233 const EMPTY: Self = $name::empty().bits();
234
235 const ALL: Self = $name::all().bits();
236 }
237
238 impl bitflags::Flags for $name {
239 const FLAGS: &'static [bitflags::Flag<Self>] = $name::FLAGS;
240
241 type Bits = $name_bits;
242
243 fn bits(&self) -> $name_bits {
244 $name_bits([
245 $(self.$lower_inner_name.bits(),)*
246 ])
247 }
248
249 fn from_bits_retain(bits: $name_bits) -> Self {
250 let [$($lower_inner_name,)*] = bits.0;
251 Self {
252 $($lower_inner_name: $inner_name::from_bits_retain($lower_inner_name),)*
253 }
254 }
255
256 fn empty() -> Self {
257 Self::empty()
258 }
259
260 fn all() -> Self {
261 Self::all()
262 }
263 }
264
265 impl $name {
266 pub(crate) const FLAGS: &'static [bitflags::Flag<Self>] = &[
267 $(
268 $(
269 bitflags::Flag::new(stringify!($Flag), $name::$Flag),
270 )*
271 )*
272 ];
273
274 pub const fn bits(&self) -> $name_bits {
276 $name_bits([
277 $(self.$lower_inner_name.bits(),)*
278 ])
279 }
280
281 pub const fn empty() -> Self {
283 Self {
284 $($lower_inner_name: $inner_name::empty(),)*
285 }
286 }
287
288 pub const fn all() -> Self {
290 Self {
291 $($lower_inner_name: $inner_name::all(),)*
292 }
293 }
294
295 pub const fn contains(self, other:Self) -> bool {
297 $(self.$lower_inner_name.contains(other.$lower_inner_name) &&)* true
299 }
300
301 pub const fn intersects(self, other:Self) -> bool {
303 $(self.$lower_inner_name.intersects(other.$lower_inner_name) ||)* false
304 }
305
306 pub const fn is_empty(self) -> bool {
308 $(self.$lower_inner_name.is_empty() &&)* true
309 }
310
311 pub const fn is_all(self) -> bool {
313 $(self.$lower_inner_name.is_all() &&)* true
314 }
315
316 $crate::bitflags_independent_two_arg! {
317 union $($lower_inner_name)*
319 }
320
321 $crate::bitflags_independent_two_arg! {
322 intersection $($lower_inner_name)*
324 }
325
326 $crate::bitflags_independent_two_arg! {
327 difference $($lower_inner_name)*
329 }
330
331 $crate::bitflags_independent_two_arg! {
332 symmetric_difference $($lower_inner_name)*
334 }
335
336 pub const fn complement(self) -> Self {
338 Self {
339 $($lower_inner_name: self.$lower_inner_name.complement(),)*
340 }
341 }
342
343 pub fn set(&mut self, other:Self, set: bool) {
345 $(self.$lower_inner_name.set(other.$lower_inner_name, set);)*
346 }
347
348 pub fn insert(&mut self, other:Self) {
350 $(self.$lower_inner_name.insert(other.$lower_inner_name);)*
351 }
352
353 pub fn remove(&mut self, other:Self) {
355 $(self.$lower_inner_name.remove(other.$lower_inner_name);)*
356 }
357
358 pub fn toggle(&mut self, other:Self) {
360 $(self.$lower_inner_name.toggle(other.$lower_inner_name);)*
361 }
362
363 #[doc = concat!("Takes in [`", stringify!($name_bits), "`] and returns")]
364 pub const fn from_bits(bits: $name_bits) -> Option<Self> {
366 let [$($lower_inner_name,)*] = bits.0;
367 Some(Self {
369 $(
370 $lower_inner_name: match $inner_name::from_bits($lower_inner_name) {
371 Some(some) => some,
372 None => return None,
373 },
374 )*
375 })
376 }
377
378 #[doc = concat!("Takes in [`", stringify!($name_bits), "`] and returns Self with only valid bits (all other bits removed)")]
379 pub const fn from_bits_truncate(bits: $name_bits) -> Self {
380 let [$($lower_inner_name,)*] = bits.0;
381 Self { $($lower_inner_name: $inner_name::from_bits_truncate($lower_inner_name),)* }
382 }
383
384 #[doc = concat!("Takes in [`", stringify!($name_bits), "`] and returns Self with all bits that were set without removing invalid bits")]
385 pub const fn from_bits_retain(bits: $name_bits) -> Self {
386 let [$($lower_inner_name,)*] = bits.0;
387 Self { $($lower_inner_name: $inner_name::from_bits_retain($lower_inner_name),)* }
388 }
389
390 pub fn from_name(name: &str) -> Option<Self> {
397 match name {
398 $(
399 $(
400 stringify!($Flag) => Some(Self::$Flag),
401 )*
402 )*
403 _ => None,
404 }
405 }
406
407 pub fn from_internal_flags($($lower_inner_name: $inner_name,)*) -> Self {
409 Self {
410 $($lower_inner_name,)*
411 }
412 }
413
414 pub const fn iter(&self) -> bitflags::iter::Iter<$name> {
416 bitflags::iter::Iter::__private_const_new($name::FLAGS, *self, *self)
417 }
418
419 pub const fn iter_names(&self) -> bitflags::iter::IterNames<$name> {
423 bitflags::iter::IterNames::__private_const_new($name::FLAGS, *self, *self)
424 }
425
426 $(
427 $(
428 $(#[doc $($args)*])*
429 #[allow(clippy::needless_update, reason = "only useless if there is 1 member")]
430 pub const $Flag: Self = Self {
431 $lower_inner_name: $inner_name::from_bits_truncate($value),
432 ..Self::empty()
433 };
434 )*
435 )*
436 }
437
438 $(
439 impl From<$inner_name> for $name {
440 #[allow(clippy::needless_update, reason = "only useless if there is 1 member")]
441 fn from($lower_inner_name: $inner_name) -> Self {
442 Self {
443 $lower_inner_name,
444 ..Self::empty()
445 }
446 }
447 }
448 )*
449 };
450 }
451pub(crate) use bitflags_array;