1use syn::{
2 parse::Parse, punctuated::Punctuated, spanned::Spanned, token::Paren, Attribute, DeriveInput,
3 Error, Expr, Ident, ItemConst, ItemEnum, LitInt, LitStr, Meta, MetaNameValue, Path, Visibility,
4};
5
6use proc_macro2::TokenStream;
7
8use quote::{quote, ToTokens, TokenStreamExt};
9
10pub struct Bitflag {
11 vis: Visibility,
12 attrs: Vec<Attribute>,
13 name: Ident,
14 inner_ty: Path,
15 repr_attr: Option<ReprAttr>,
16 derived_traits: Vec<Path>,
17 impl_flags: ImplFlags,
18 all_attrs: Vec<Vec<Attribute>>,
19 all_flags: Vec<TokenStream>,
20 all_flags_names: Vec<LitStr>,
21 flags: Vec<ItemConst>,
22 default_value: Option<Expr>,
23 custom_known_bits: Option<Expr>,
24 orig_enum: ItemEnum,
25}
26
27impl Bitflag {
28 pub fn parse(args: Args, item: proc_macro::TokenStream) -> syn::Result<Self> {
29 let ty = args.ty;
30
31 let item: DeriveInput = syn::parse(item)?;
32 let item_span = item.span();
33 let ident_span = item.ident.span();
34 let og_attrs = item.attrs.iter().filter(|att| {
35 !att.path().is_ident("derive")
36 && !att.path().is_ident("reserved_bits")
37 && !att.path().is_ident("repr")
38 && !att.path().is_ident("serde")
39 });
40
41 let vis = item.vis;
42 let name = item.ident;
43
44 let has_non_exhaustive = item
45 .attrs
46 .iter()
47 .any(|att| att.path().is_ident("non_exhaustive"));
48
49 let serde_helper = item.attrs.iter().find(|att| att.path().is_ident("serde"));
50
51 if let Some(serde) = serde_helper {
52 return Err(Error::new(
53 serde.span(),
54 "`serde` helper attribute is not compatible with `bitflag` attribute: in this case, manual implementation of serde traits should be considered",
55 ));
56 }
57
58 let attrs = item
60 .attrs
61 .iter()
62 .filter(|att| {
63 !att.path().is_ident("derive")
64 && !att.path().is_ident("reserved_bits")
65 && !att.path().is_ident("repr")
66 })
67 .cloned()
68 .collect();
69
70 let repr_attr = item
71 .attrs
72 .iter()
73 .find(|att| att.path().is_ident("repr"))
74 .map(|att| syn::parse2::<ReprAttr>(att.meta.to_token_stream()));
75
76 let repr_attr = match repr_attr {
77 Some(repr) => {
78 use ReprKind::*;
79 let repr = repr?;
80
81 match repr.kinds() {
83 (None, None) | (None, Some(_)) => {}
85 (Some(Rust(_) | C(_) | Transparent(_)), None) => {}
87 (Some(kind), None)
89 | (Some(Rust(_) | C(_)), Some(kind))
90 | (Some(kind), Some(Rust(_) | C(_))) => {
91 return Err(Error::new(
92 kind.span(),
93 "`bitflag` unsupported repr: Supported repr are `C`, `Rust` and `transparent`",
94 ));
95 }
96 _ => {}
102 }
103 Some(repr)
104 }
105 None => None,
106 };
107
108 let valid_bits_attr = item
109 .attrs
110 .iter()
111 .find(|att| att.path().is_ident("reserved_bits"));
112
113 let derives = item
114 .attrs
115 .iter()
116 .filter(|att| att.path().is_ident("derive"));
117
118 let mut derived_traits = Vec::new();
119 let mut impl_flags = ImplFlags::empty();
120 let mut clone_found = false;
121 let mut copy_found = false;
122
123 for derive in derives {
124 derive.parse_nested_meta(|meta| {
125 let s = meta.path.to_token_stream().to_string().replace(" ", "");
126 match s.as_str() {
127 "Debug" => {
128 impl_flags |= ImplFlags::DEBUG;
129 return Ok(());
130 }
131 "Default" => {
132 impl_flags |= ImplFlags::DEFAULT;
133 return Ok(());
134 }
135 "Serialize" | "serde::Serialize" | "::serde::Serialize"
136 if cfg!(feature = "serde") =>
137 {
138 impl_flags |= ImplFlags::SERIALIZE;
139 return Ok(());
140 }
141 "Deserialize" | "serde::Deserialize" | "::serde::Deserialize"
142 if cfg!(feature = "serde") =>
143 {
144 impl_flags |= ImplFlags::DESERIALIZE;
145 return Ok(());
146 }
147 "Arbitrary" | "arbitrary::Arbitrary" | "::arbitrary::Arbitrary"
148 if cfg!(feature = "arbitrary") =>
149 {
150 impl_flags |= ImplFlags::ARBITRARY;
151 return Ok(());
152 }
153 "Pod" | "bytemuck::Pod" | "::bytemuck::Pod" if cfg!(feature = "bytemuck") => {
154 if repr_attr.is_none() {
157 impl_flags |= ImplFlags::POD;
158 return Ok(());
159 }
160
161 if let Some(repr_attr) = &repr_attr {
162 match repr_attr.kinds() {
163 (Some(ReprKind::Transparent(_) | ReprKind::C(_)), None)
168 | (
169 Some(ReprKind::C(_)),
170 Some(ReprKind::Packed(_, _) | ReprKind::Align(_, _)),
171 ) => {
172 impl_flags |= ImplFlags::POD;
173 return Ok(());
174 }
175 _ => {
176 return Err(Error::new(
177 meta.path.span(),
178 format!(
179 "bitflag: deriving `Pod` for `{}` is not compatible",
180 repr_attr.to_token_stream()
181 ),
182 ))
183 }
184 }
185 }
186 }
187 "Zeroable" | "bytemuck::Zeroable" | "::bytemuck::Zeroable"
188 if cfg!(feature = "bytemuck") =>
189 {
190 impl_flags |= ImplFlags::ZEROABLE;
191 return Ok(());
192 }
193 path => {
194 if path == "Clone" {
195 clone_found = true;
196 }
197
198 if path == "Copy" {
199 copy_found = true;
200 }
201
202 derived_traits.push(meta.path);
203 }
204 }
205 Ok(())
206 })?;
207 }
208
209 if !clone_found || !copy_found {
210 return Err(syn::Error::new(
211 item_span,
212 "`bitflags` attribute requires the type to derive `Clone` and `Copy`",
213 ));
214 }
215
216 let enun = if let syn::Data::Enum(e) = item.data {
217 e
218 } else {
219 return Err(syn::Error::new(
220 ident_span,
221 "the type for `bitflag` must be a `enum` (that will be turned into a `struct`)",
222 ));
223 };
224 let number_flags = enun.variants.len();
225
226 let mut all_attrs = Vec::with_capacity(number_flags);
227 let mut all_flags = Vec::with_capacity(number_flags);
228 let mut all_flags_names = Vec::with_capacity(number_flags);
229 let mut all_variants = Vec::with_capacity(number_flags);
230 let mut all_non_doc_attrs = Vec::with_capacity(number_flags);
231 let mut default_value = None;
232
233 let mut raw_flags = Vec::with_capacity(number_flags);
235
236 let mut flags = Vec::with_capacity(number_flags); for variant in enun.variants.iter() {
240 let var_attrs = &variant.attrs;
241 let var_name = &variant.ident;
242
243 if !variant.fields.is_empty() {
244 let span = variant.fields.span();
245 return Err(Error::new(
246 span,
247 "an enum with `bitflag` attribute can not have a field",
248 ));
249 }
250
251 let expr = match variant.discriminant.as_ref() {
252 Some((_, expr)) => expr,
253 None => {
254 return Err(Error::new_spanned(
255 variant,
256 "a discriminant must be defined",
257 ))
258 }
259 };
260
261 let serde_helper = var_attrs.iter().find(|attr| attr.path().is_ident("serde"));
262
263 if let Some(serde) = serde_helper {
264 return Err(Error::new(
265 serde.span(),
266 "`serde` helper attribute is not compatible with `bitflag` attribute: in this case, manual implementation of serde traits should be considered",
267 ));
268 }
269
270 let default_attr = var_attrs
271 .iter()
272 .find(|attr| attr.path().is_ident("default"));
273
274 if let Some(default) = default_attr {
275 if !impl_flags.contains(ImplFlags::DEFAULT) {
276 return Err(Error::new(
277 default.span(),
278 "`default` attribute without `#[derive(Default)]`",
279 ));
280 }
281
282 default_value = Some(syn::parse2(quote!(Self::#var_name))?);
283 }
284
285 let non_doc_attrs: Vec<Attribute> = var_attrs
286 .iter()
287 .filter(|attr| !attr.path().is_ident("doc"))
288 .cloned()
289 .collect();
290
291 let filtered_attrs = var_attrs
292 .iter()
293 .filter(|attr| !attr.path().is_ident("doc") && !attr.path().is_ident("default"));
294
295 all_flags.push(quote!(#name::#var_name));
296 all_flags_names.push(syn::LitStr::new(&var_name.to_string(), var_name.span()));
297 all_variants.push(var_name.clone());
298 all_attrs.push(filtered_attrs.clone().cloned().collect::<Vec<_>>());
299 all_non_doc_attrs.push(non_doc_attrs.clone());
300 raw_flags.push(quote! {
301 #(#filtered_attrs)*
302 #[allow(non_upper_case_globals, dead_code, unused)]
303 const #var_name: #ty = #expr;
304 });
305 }
306
307 for variant in enun.variants.iter() {
308 let var_attrs = &variant.attrs;
309 let var_name = &variant.ident;
310
311 let expr = match variant.discriminant.as_ref() {
312 Some((_, expr)) => expr,
313 None => {
314 return Err(Error::new_spanned(
315 variant,
316 "a discriminant must be defined",
317 ))
318 }
319 };
320
321 let all_attr = var_attrs
322 .iter()
323 .filter(|attr| !attr.path().is_ident("default"));
324
325 let generated = if can_simplify(expr, &all_variants) {
326 quote! {
327 #(#all_attr)*
328 #vis const #var_name: Self = Self(#expr);
329 }
330 } else {
331 quote! {
332 #(#all_attr)*
333 #vis const #var_name: Self = {
334 #(#raw_flags)*
335
336 Self(#expr)
337 };
338 }
339 };
340
341 flags.push(syn::parse2(generated)?);
342 }
343
344 let og_derive = (impl_flags.contains(ImplFlags::DEFAULT) && default_value.is_some())
345 .then(|| quote!(#[derive(Default)]));
346 let orig_enum = syn::parse2(quote! {
347 #[allow(dead_code)]
348 #(#og_attrs)*
349 #og_derive
350 enum #name {
351 #(
352 #(#all_non_doc_attrs)*
353 #all_variants,
354 )*
355 }
356 })?;
357
358 let custom_known_bits: Option<Expr> = if let Some(attr) = valid_bits_attr {
359 let parsed = ExtraValidBits::from_meta(&attr.meta)?;
360
361 Some(parsed.0)
362 } else if has_non_exhaustive {
363 Some(syn::parse2(quote! {!0})?)
364 } else {
365 None
366 };
367
368 Ok(Self {
369 vis,
370 attrs,
371 name,
372 inner_ty: ty,
373 derived_traits,
374 repr_attr,
375 impl_flags,
376 all_attrs,
377 all_flags,
378 all_flags_names,
379 default_value,
380 flags,
381 custom_known_bits,
382 orig_enum,
383 })
384 }
385}
386
387impl ToTokens for Bitflag {
388 fn to_tokens(&self, tokens: &mut TokenStream) {
389 let Self {
390 vis,
391 attrs,
392 name,
393 inner_ty,
394 repr_attr,
395 derived_traits,
396 impl_flags,
397 all_attrs,
398 all_flags,
399 all_flags_names,
400 default_value,
401 flags,
402 custom_known_bits,
403 orig_enum,
404 } = self;
405
406 let reserved_bits = custom_known_bits
407 .as_ref()
408 .map(|expr| quote! {all |= #expr;});
409
410 let reserved_bits_value = if let Some(expr) = custom_known_bits {
411 quote! {#expr}
412 } else {
413 quote! {
414 {
415 let mut all = 0;
416
417 #(
418 #(#all_attrs)*{
419 all |= #all_flags.0;
420 }
421 )*
422
423 all
424 }
425 }
426 };
427
428 let repr_attr = match repr_attr {
429 Some(repr) => {
430 quote! {#repr}
431 }
432 None => quote! {#[repr(transparent)]},
433 };
434
435 let const_mut = cfg!(feature = "const-mut-ref").then(|| quote!(const));
436
437 let debug_impl = impl_flags.contains(ImplFlags::DEBUG).then(|| {
438 quote! {
439 #[automatically_derived]
440 impl ::core::fmt::Debug for #name {
441 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
442 struct HumanReadable<'a>(&'a #name);
443
444 impl<'a> ::core::fmt::Debug for HumanReadable<'a> {
445 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
446 if self.0.is_empty() {
447 ::core::write!(f, "{:#X}", self.0.0)
448 } else {
449 ::bitflag_attr::parser::to_writer(self.0, f)
450 }
451 }
452 }
453
454 #[inline]
455 pub const fn octal_width() -> usize {
456 match #inner_ty::BITS as usize {
457 8 => 3,
458 16 => 6,
459 32 => 11,
460 64 => 22,
461 128 => 43,
462 x => x/3 + x%3
464 }
465 }
466
467 let name = ::core::stringify!(#name);
468
469 f.debug_struct(name)
470 .field("flags", &HumanReadable(self))
471 .field("bits", &::core::format_args!("{:#0width$b}", self.0, width = 2 + #inner_ty::BITS as usize))
473 .field("octal", &::core::format_args!("{:#0width$o}", self.0, width = 2 + const { octal_width() }))
474 .field("hex", &::core::format_args!("{:#0width$X}", self.0, width = 2 + const {#inner_ty::BITS as usize/4}))
475 .finish()
476 }
477 }
478 }
479 });
480
481 let default_impl = impl_flags.contains(ImplFlags::DEFAULT).then(|| {
482 if let Some(expr) = default_value {
483 quote! {
484 #[automatically_derived]
485 impl ::core::default::Default for #name {
486 #[inline]
487 fn default() -> Self {
488 #expr
489 }
490 }
491 }
492 } else {
493 quote! {
494 #[automatically_derived]
495 impl ::core::default::Default for #name {
496 #[inline]
497 fn default() -> Self {
498 Self(<#inner_ty as ::core::default::Default>::default())
499 }
500 }
501 }
502 }
503 });
504
505 let serialize_impl = (cfg!(feature = "serde") && impl_flags.contains(ImplFlags::SERIALIZE)).then(|| {
506 quote! {
507 #[automatically_derived]
508 impl ::serde::Serialize for #name {
509 fn serialize<S>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error>
510 where
511 S: ::serde::Serializer
512 {
513 struct AsDisplay<'a>(&'a #name);
514
515 impl<'a> ::core::fmt::Display for AsDisplay<'a> {
516 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
517 ::bitflag_attr::parser::to_writer(self.0, f)
518 }
519 }
520
521 if serializer.is_human_readable() {
523 serializer.collect_str(&AsDisplay(self))
524 }
525 else {
527 self.bits().serialize(serializer)
528 }
529 }
530 }
531 }
532 });
533
534 let deserialize_impl = (cfg!(feature = "serde") && impl_flags.contains(ImplFlags::DESERIALIZE)).then(|| {
535 quote! {
536 #[automatically_derived]
537 impl<'de> ::serde::Deserialize<'de> for #name {
538 fn deserialize<D>(deserializer: D) -> ::core::result::Result<Self, D::Error>
539 where
540 D: ::serde::Deserializer<'de>
541 {
542 if deserializer.is_human_readable() {
543 struct HelperVisitor(::core::marker::PhantomData<#name>);
544
545 impl<'de> ::serde::de::Visitor<'de> for HelperVisitor {
546 type Value = #name;
547
548 fn expecting(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
549 f.write_str("a string value of `|` separated flags")
550 }
551
552 fn visit_str<E>(self, flags: &str) -> ::core::result::Result<Self::Value, E>
553 where
554 E: ::serde::de::Error,
555 {
556 ::bitflag_attr::parser::from_text(flags).map_err(|e| E::custom(e))
557 }
558 }
559
560 deserializer.deserialize_str(HelperVisitor(::core::marker::PhantomData))
561 } else {
562 let bits = #inner_ty::deserialize(deserializer)?;
563
564 ::core::result::Result::Ok(#name::from_bits_retain(bits))
565 }
566 }
567 }
568 }
569 });
570
571 let arbitrary_impl = (cfg!(feature = "arbitrary") && impl_flags.contains(ImplFlags::ARBITRARY)).then(|| {
572 quote! {
573 #[automatically_derived]
574 impl<'a> ::arbitrary::Arbitrary<'a> for #name {
575 fn arbitrary(u: &mut ::arbitrary::Unstructured<'a>) -> ::arbitrary::Result<Self> {
576 #name::from_bits(u.arbitrary()?).ok_or(::arbitrary::Error::IncorrectFormat)
577 }
578 }
579 }
580 });
581
582 let pod_impl =
583 (cfg!(feature = "bytemuck") && impl_flags.contains(ImplFlags::POD)).then(|| {
584 let error_str = LitStr::new(
585 &format!(
586 "`bitflag` error: type `{name}` not compatible with the `bytemuck::Pod` trait."
587 ),
588 name.span(),
589 );
590 quote! {
591 #[doc(hidden)]
593 const _: () = {
594 if ::core::mem::size_of::<#name>() != ::core::mem::size_of::<#inner_ty>() {
595 ::core::panic!(#error_str);
596 }
597 };
598 #[automatically_derived]
599 unsafe impl ::bytemuck::Pod for #name {}
600 }
601 });
602
603 let zeroable_impl =
604 (cfg!(feature = "bytemuck") && impl_flags.contains(ImplFlags::ZEROABLE)).then(|| {
605 quote! {
606 #[automatically_derived]
607 unsafe impl ::bytemuck::Zeroable for #name {}
608 }
609 });
610
611 let doc_from_iter = format!("Create a `{name}` from a iterator of flags.");
612 let generated = quote! {
613 #repr_attr
614 #(#attrs)*
615 #[derive(#(#derived_traits,)*)]
616 #vis struct #name(#inner_ty)
617 where
618 #inner_ty: ::bitflag_attr::BitsPrimitive;
619
620 #[doc(hidden)]
621 #[allow(clippy::unused_unit)]
622 const _: () = {
623 {
624 #orig_enum
627 }
628 ()
629 };
630
631 #[allow(non_upper_case_globals)]
632 impl #name {
633 #(#flags)*
634 }
635
636 #[allow(non_upper_case_globals)]
637 impl #name {
638 #[inline]
640 pub const fn bits(&self) -> #inner_ty {
641 self.0
642 }
643
644 #[inline]
646 pub const fn from_bits(bits: #inner_ty) -> ::core::option::Option<Self> {
647 let truncated = Self::from_bits_truncate(bits).0;
648
649 if truncated == bits {
650 ::core::option::Option::Some(Self(bits))
651 } else {
652 ::core::option::Option::None
653 }
654 }
655
656 #[inline]
658 pub const fn from_bits_truncate(bits: #inner_ty) -> Self {
659 Self(bits & Self::all().0)
660 }
661
662 #[inline]
664 pub const fn from_bits_retain(bits: #inner_ty) -> Self {
665 Self(bits)
666 }
667
668 #[inline]
670 pub fn from_flag_name(name: &str) -> ::core::option::Option<Self> {
671 match name {
672 #(
673 #(#all_attrs)*
674 #all_flags_names => ::core::option::Option::Some(#all_flags),
675 )*
676 _ => ::core::option::Option::None
677 }
678 }
679
680 #[inline]
682 pub const fn empty() -> Self {
683 Self(0)
684 }
685
686 #[inline]
688 pub const fn is_empty(&self) -> bool {
689 self.0 == 0
690 }
691
692 #[inline]
697 pub const fn all_bits() -> Self {
698 Self(!0)
699 }
700
701 #[inline]
706 pub const fn is_all_bits(&self) -> bool {
707 self.0 == !0
708 }
709
710 #[inline]
715 pub const fn all() -> Self {
716 let mut all = 0;
717
718 #(
719 #(#all_attrs)*{
720 all |= #all_flags.0;
721 }
722 )*
723
724 #reserved_bits
725
726 Self(all)
727 }
728
729 #[inline]
731 pub const fn is_all(&self) -> bool {
732 Self::all().0 | self.0 == self.0
733 }
734
735 #[inline]
740 pub const fn all_named() -> Self {
741 let mut all = 0;
742
743 #(
744 #(#all_attrs)*{
745 all |= #all_flags.0;
746 }
747 )*
748
749 Self(all)
750 }
751
752 #[inline]
754 pub const fn is_all_named(&self) -> bool {
755 Self::all_named().0 | self.0 == self.0
756 }
757
758 #[inline]
760 pub const fn contains_unknown_bits(&self) -> bool {
761 Self::all().0 & self.0 != self.0
762 }
763
764 #[inline]
766 pub const fn contains_unnamed_bits(&self) -> bool {
767 Self::all_named().0 & self.0 != self.0
768 }
769
770 #[inline]
772 pub const fn truncated(&self) -> Self {
773 Self(self.0 & Self::all().0)
774 }
775
776 #[inline]
778 pub #const_mut fn truncate(&mut self) {
779 *self = Self::from_bits_truncate(self.0);
780 }
781
782 #[inline]
786 pub const fn intersects(&self, other: Self) -> bool {
787 (self.0 & other.0) != Self::empty().0
788 }
789
790 #[inline]
794 pub const fn contains(&self, other: Self) -> bool {
795 (self.0 & other.0) == other.0
796 }
797
798 #[inline]
803 #[doc(alias = "complement")]
804 pub const fn not(self) -> Self {
805 Self(!self.0)
806 }
807
808 #[inline]
810 #[doc(alias = "intersection")]
811 pub const fn and(self, other: Self) -> Self {
812 Self(self.0 & other.0)
813 }
814
815 #[inline]
817 #[doc(alias = "union")]
818 pub const fn or(self, other: Self) -> Self {
819 Self(self.0 | other.0)
820 }
821
822 #[inline]
824 #[doc(alias = "symmetric_difference")]
825 pub const fn xor(self, other: Self) -> Self {
826 Self(self.0 ^ other.0)
827 }
828
829 #[inline]
831 #[doc(alias = "and")]
832 pub const fn intersection(self, other: Self) -> Self {
833 self.and(other)
834 }
835
836 #[inline]
838 #[doc(alias = "or")]
839 pub const fn union(self, other: Self) -> Self {
840 self.or(other)
841 }
842
843 #[inline]
850 pub const fn difference(self, other: Self) -> Self {
851 self.and(other.not())
852 }
853
854 #[inline]
856 #[doc(alias = "xor")]
857 pub const fn symmetric_difference(self, other: Self) -> Self {
858 self.xor(other)
859 }
860
861 #[inline]
865 #[doc(alias = "not")]
866 pub const fn complement(self) -> Self {
867 self.not().truncated()
868 }
869
870 #[inline]
872 #[doc(alias = "insert")]
873 pub #const_mut fn set(&mut self, other: Self) {
874 self.0 = self.or(other).0
875 }
876
877 #[inline]
879 #[doc(alias = "remove")]
880 pub #const_mut fn unset(&mut self, other: Self) {
881 self.0 = self.difference(other).0
882 }
883
884 #[inline]
886 pub #const_mut fn toggle(&mut self, other: Self) {
887 self.0 = self.xor(other).0
888 }
889
890 #[inline]
892 pub #const_mut fn clear(&mut self) {
893 self.0 = 0
894 }
895 }
896
897 #[automatically_derived]
898 impl ::core::ops::Not for #name {
899 type Output = Self;
900
901 #[inline]
902 fn not(self) -> Self::Output {
903 self.complement()
904 }
905 }
906
907 #[automatically_derived]
908 impl ::core::ops::BitAnd for #name {
909 type Output = Self;
910
911 #[inline]
912 fn bitand(self, rhs: Self) -> Self::Output {
913 self.and(rhs)
914 }
915 }
916
917 #[automatically_derived]
918 impl ::core::ops::BitOr for #name {
919 type Output = Self;
920
921 #[inline]
922 fn bitor(self, rhs: Self) -> Self::Output {
923 self.or(rhs)
924 }
925 }
926
927 #[automatically_derived]
928 impl ::core::ops::BitXor for #name {
929 type Output = Self;
930
931 #[inline]
932 fn bitxor(self, rhs: Self) -> Self::Output {
933 self.xor(rhs)
934 }
935 }
936
937 #[automatically_derived]
938 impl ::core::ops::BitAndAssign for #name {
939 #[inline]
940 fn bitand_assign(&mut self, rhs: Self) {
941 *self = self.and(rhs)
942 }
943 }
944
945 #[automatically_derived]
946 impl ::core::ops::BitOrAssign for #name {
947 #[inline]
948 fn bitor_assign(&mut self, rhs: Self) {
949 *self = self.or(rhs)
950 }
951 }
952
953 #[automatically_derived]
954 impl ::core::ops::BitXorAssign for #name {
955 #[inline]
956 fn bitxor_assign(&mut self, rhs: Self) {
957 *self = self.xor(rhs)
958 }
959 }
960
961 #[automatically_derived]
962 impl ::core::ops::Sub for #name {
963 type Output = Self;
964
965 #[inline]
967 fn sub(self, rhs: Self) -> Self::Output {
968 self.difference(rhs)
969 }
970 }
971
972 #[automatically_derived]
973 impl ::core::ops::SubAssign for #name {
974 #[inline]
976 fn sub_assign(&mut self, rhs: Self) {
977 self.unset(rhs)
978 }
979 }
980
981 #[automatically_derived]
982 impl ::core::convert::From<#inner_ty> for #name {
983 #[inline]
984 fn from(val: #inner_ty) -> Self {
985 Self::from_bits_truncate(val)
986 }
987 }
988
989 #[automatically_derived]
990 impl ::core::convert::From<#name> for #inner_ty {
991 #[inline]
992 fn from(val: #name) -> Self {
993 val.0
994 }
995 }
996
997 #[automatically_derived]
998 impl ::core::fmt::Binary for #name {
999 #[inline]
1000 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1001 ::core::fmt::Binary::fmt(&self.0, f)
1002 }
1003 }
1004
1005 #[automatically_derived]
1006 impl ::core::fmt::LowerHex for #name {
1007 #[inline]
1008 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1009 ::core::fmt::LowerHex::fmt(&self.0, f)
1010 }
1011 }
1012
1013 #[automatically_derived]
1014 impl ::core::fmt::UpperHex for #name {
1015 #[inline]
1016 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1017 ::core::fmt::UpperHex::fmt(&self.0, f)
1018 }
1019 }
1020
1021 #[automatically_derived]
1022 impl ::core::fmt::Octal for #name {
1023 #[inline]
1024 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1025 ::core::fmt::Octal::fmt(&self.0, f)
1026 }
1027 }
1028
1029 #[automatically_derived]
1030 impl ::core::str::FromStr for #name {
1031 type Err = ::bitflag_attr::parser::ParseError;
1032
1033 #[inline]
1034 fn from_str(input: &str) -> ::core::result::Result<Self, Self::Err> {
1035 ::bitflag_attr::parser::from_text(input)
1036 }
1037 }
1038
1039 #debug_impl
1040
1041 #default_impl
1042
1043 #[automatically_derived]
1044 impl ::bitflag_attr::Flags for #name {
1045 const NAMED_FLAGS: &'static [(&'static str, #name)] = &[#(
1046 #(#all_attrs)*
1047 (#all_flags_names , #all_flags) ,
1048 )*];
1049
1050 const RESERVED_BITS: #inner_ty = #reserved_bits_value;
1051
1052 type Bits = #inner_ty;
1053
1054 #[inline]
1055 fn bits(&self) -> Self::Bits {
1056 self.0
1057 }
1058
1059 #[inline]
1060 fn from_bits_retain(bits: Self::Bits) -> Self {
1061 Self(bits)
1062 }
1063 }
1064
1065 impl #name {
1066 const NAMED_FLAGS: &'static [(&'static str, #name)] = &[#(
1067 #(#all_attrs)*
1068 (#all_flags_names , #all_flags) ,
1069 )*];
1070
1071 #[inline]
1076 pub const fn iter(&self) -> ::bitflag_attr::iter::Iter<Self> {
1077 ::bitflag_attr::iter::Iter::__private_const_new(Self::NAMED_FLAGS, *self, *self)
1078 }
1079
1080 #[inline]
1085 pub const fn iter_names(&self) -> ::bitflag_attr::iter::IterNames<Self> {
1086 ::bitflag_attr::iter::IterNames::__private_const_new(Self::NAMED_FLAGS, *self, *self)
1087 }
1088 }
1089
1090 #[automatically_derived]
1091 impl ::core::iter::Extend<#name> for #name {
1092 fn extend<T: ::core::iter::IntoIterator<Item = Self>>(&mut self, iter: T) {
1094 for item in iter {
1095 self.set(item);
1096 }
1097 }
1098 }
1099
1100 #[automatically_derived]
1101 impl ::core::iter::FromIterator<#name> for #name {
1102 #[doc = #doc_from_iter]
1103 fn from_iter<T: ::core::iter::IntoIterator<Item = Self>>(iter: T) -> Self {
1104 use ::core::iter::Extend;
1105
1106 let mut res = Self::empty();
1107 res.extend(iter);
1108 res
1109 }
1110 }
1111
1112 #[automatically_derived]
1113 impl ::core::iter::IntoIterator for #name {
1114 type Item = Self;
1115 type IntoIter = ::bitflag_attr::iter::Iter<Self>;
1116
1117 #[inline]
1118 fn into_iter(self) -> Self::IntoIter {
1119 self.iter()
1120 }
1121 }
1122
1123 #[automatically_derived]
1124 impl ::core::iter::IntoIterator for &#name {
1125 type Item = #name;
1126 type IntoIter = ::bitflag_attr::iter::Iter<#name>;
1127
1128 #[inline]
1129 fn into_iter(self) -> Self::IntoIter {
1130 self.iter()
1131 }
1132 }
1133
1134 #serialize_impl
1135 #deserialize_impl
1136 #arbitrary_impl
1137 #pod_impl
1138 #zeroable_impl
1139 };
1140
1141 tokens.append_all(generated);
1142 }
1143}
1144
1145pub struct Args {
1146 ty: Path,
1147}
1148
1149impl Parse for Args {
1150 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
1151 let ty: Path = input.parse().map_err(|err| {
1152 Error::new(err.span(), "unexpected token: expected a `{integer}` type")
1153 })?;
1154
1155 if !cfg!(feature = "custom-types") {
1156 let path_s = ty.to_token_stream().to_string().replace(" ", "");
1157 if !VALID_TYPES.contains(&path_s.as_str()) {
1158 return Err(Error::new_spanned(ty, "type must be a `{integer}` type"));
1159 }
1160 }
1161
1162 Ok(Args { ty })
1163 }
1164}
1165
1166struct ExtraValidBits(Expr);
1167
1168impl ExtraValidBits {
1169 fn from_meta(meta: &Meta) -> syn::Result<Self> {
1170 match meta {
1171 Meta::NameValue(m) => {
1172 if !m.path.is_ident("reserved_bits") {
1173 return Err(Error::new(
1174 m.span(),
1175 "not a valid `reserved_bits` attribute",
1176 ));
1177 }
1178
1179 Ok(Self(m.value.clone()))
1180 }
1181 _ => Err(Error::new(
1182 meta.span(),
1183 "reserved_bits must follow the syntax `reserved_bits = <expr>`",
1184 )),
1185 }
1186 }
1187}
1188
1189impl Parse for ExtraValidBits {
1190 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
1191 let meta: MetaNameValue = input.parse()?;
1192
1193 if !meta.path.is_ident("reserved_bits") {
1194 return Err(Error::new(meta.span(), "not a `reserved_bits` attribute"));
1195 }
1196
1197 Ok(Self(meta.value))
1198 }
1199}
1200
1201struct ReprAttr {
1202 path: Path,
1203 _paren_token: Paren,
1204 kinds: Punctuated<ReprKind, syn::Token![,]>,
1205}
1206
1207impl ReprAttr {
1208 pub fn kinds(&self) -> (Option<ReprKind>, Option<ReprKind>) {
1209 (self.kinds.get(0).cloned(), self.kinds.get(1).cloned())
1210 }
1211}
1212
1213impl Parse for ReprAttr {
1214 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
1215 let path: Path = input.parse()?;
1216
1217 let content;
1218 let _paren_token = syn::parenthesized!(content in input);
1219
1220 if !path.is_ident("repr") {
1221 return Err(Error::new(path.span(), "not a `#[repr]` attribute"));
1222 }
1223
1224 let mut kinds = Punctuated::new();
1225
1226 while !content.is_empty() {
1227 let first: ReprKind = content.parse()?;
1228 kinds.push_value(first);
1229 if content.is_empty() {
1230 break;
1231 }
1232 let punct = content.parse()?;
1233 kinds.push_punct(punct);
1234 }
1235
1236 Ok(Self {
1237 path,
1238 _paren_token,
1239 kinds,
1240 })
1241 }
1242}
1243
1244impl ToTokens for ReprAttr {
1245 fn to_tokens(&self, tokens: &mut TokenStream) {
1246 let Self { path, kinds, .. } = self;
1247 tokens.append_all(quote! {#[#path(#kinds)]});
1248 }
1249}
1250
1251#[derive(Clone)]
1253enum ReprKind {
1254 C(Path),
1255 Rust(Path),
1256 Transparent(Path),
1257 Integer(Path),
1258 Packed(Path, Option<LitInt>),
1259 Align(Path, LitInt),
1260}
1261
1262impl Parse for ReprKind {
1263 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
1264 let meta: Meta = input.parse()?;
1265
1266 match meta {
1267 Meta::Path(path) => {
1268 let text = path
1269 .get_ident()
1270 .map(|p| p.to_string())
1271 .unwrap_or("".to_string());
1272
1273 match text.as_str() {
1274 "C" => Ok(Self::C(path)),
1275 "Rust" => Ok(Self::Rust(path)),
1276 "transparent" => Ok(Self::Transparent(path)),
1277 "packed" => Ok(Self::Packed(path, None)),
1278 x if VALID_REPR_INT.contains(&x) => Ok(Self::Integer(path)),
1279 _ => Err(Error::new(path.span(), "invalid `repr` kind")),
1280 }
1281 }
1282 Meta::List(list) => {
1283 let text = list
1284 .path
1285 .get_ident()
1286 .map(|p| p.to_string())
1287 .unwrap_or("".to_string());
1288
1289 match text.as_str() {
1290 "packed" => {
1291 let lit = syn::parse2(list.tokens)?;
1292 Ok(Self::Packed(list.path, Some(lit)))
1293 }
1294 "align" => {
1295 let lit = syn::parse2(list.tokens)?;
1296 Ok(Self::Align(list.path, lit))
1297 }
1298 _ => Err(Error::new(list.span(), "invalid `repr` kind")),
1299 }
1300 }
1301 _ => Err(Error::new(meta.span(), "invalid `repr` kind")),
1302 }
1303 }
1304}
1305
1306impl ToTokens for ReprKind {
1307 fn to_tokens(&self, tokens: &mut TokenStream) {
1308 match self {
1309 ReprKind::C(path)
1310 | ReprKind::Rust(path)
1311 | ReprKind::Transparent(path)
1312 | ReprKind::Integer(path)
1313 | ReprKind::Packed(path, None) => tokens.append_all(quote!(#path)),
1314
1315 ReprKind::Packed(path, Some(lit_int)) | ReprKind::Align(path, lit_int) => {
1316 tokens.append_all(quote!(#path(#lit_int)))
1317 }
1318 }
1319 }
1320}
1321
1322const VALID_REPR_INT: &[&str] = &[
1323 "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "i128", "u128",
1324];
1325
1326#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
1328struct ImplFlags(u8);
1329
1330impl ImplFlags {
1331 pub const DEBUG: Self = Self(1);
1332 pub const DEFAULT: Self = Self(1 << 1);
1333 pub const SERIALIZE: Self = Self(1 << 2);
1334 pub const DESERIALIZE: Self = Self(1 << 3);
1335 pub const ARBITRARY: Self = Self(1 << 4);
1336 pub const ZEROABLE: Self = Self(1 << 5);
1337 pub const POD: Self = Self(1 << 6);
1338
1339 pub const fn empty() -> Self {
1340 Self(0)
1341 }
1342
1343 pub const fn contains(&self, other: Self) -> bool {
1344 (self.0 & other.0) == other.0
1345 }
1346}
1347
1348impl core::ops::Not for ImplFlags {
1349 type Output = Self;
1350
1351 #[inline]
1352 fn not(self) -> Self::Output {
1353 Self(!self.0)
1354 }
1355}
1356
1357impl core::ops::BitAnd for ImplFlags {
1358 type Output = Self;
1359
1360 #[inline]
1361 fn bitand(self, rhs: Self) -> Self::Output {
1362 Self(self.0 & rhs.0)
1363 }
1364}
1365
1366impl core::ops::BitOr for ImplFlags {
1367 type Output = Self;
1368
1369 #[inline]
1370 fn bitor(self, rhs: Self) -> Self::Output {
1371 Self(self.0 | rhs.0)
1372 }
1373}
1374
1375impl core::ops::BitXor for ImplFlags {
1376 type Output = Self;
1377
1378 #[inline]
1379 fn bitxor(self, rhs: Self) -> Self::Output {
1380 Self(self.0 ^ rhs.0)
1381 }
1382}
1383
1384impl core::ops::BitAndAssign for ImplFlags {
1385 #[inline]
1386 fn bitand_assign(&mut self, rhs: Self) {
1387 *self = Self(self.0 & rhs.0)
1388 }
1389}
1390
1391impl core::ops::BitOrAssign for ImplFlags {
1392 #[inline]
1393 fn bitor_assign(&mut self, rhs: Self) {
1394 *self = Self(self.0 | rhs.0)
1395 }
1396}
1397
1398impl core::ops::BitXorAssign for ImplFlags {
1399 #[inline]
1400 fn bitxor_assign(&mut self, rhs: Self) {
1401 *self = Self(self.0 ^ rhs.0)
1402 }
1403}
1404
1405fn can_simplify(expr: &syn::Expr, variants: &[Ident]) -> bool {
1421 match expr {
1422 syn::Expr::Lit(_) => true,
1423 syn::Expr::Path(expr_path) if is_simple_path(expr_path, variants) => true,
1424 syn::Expr::Unary(expr_unary) => can_simplify(&expr_unary.expr, variants),
1425 syn::Expr::Binary(expr_binary) => {
1426 can_simplify(&expr_binary.left, variants) && can_simplify(&expr_binary.right, variants)
1427 }
1428 syn::Expr::Paren(expr_paren) => can_simplify(&expr_paren.expr, variants),
1429 syn::Expr::Cast(expr_cast) => can_simplify(&expr_cast.expr, variants),
1430 _ => false,
1431 }
1432}
1433
1434fn is_simple_path(expr: &syn::ExprPath, variants: &[Ident]) -> bool {
1435 if expr.qself.is_some() {
1436 return false;
1437 }
1438
1439 if let Some(ident) = expr.path.get_ident() {
1441 if !variants.contains(ident) {
1443 return true;
1444 }
1445 }
1446
1447 if expr.path.segments.iter().count() >= 2 {
1451 return true;
1452 }
1453
1454 false
1455}
1456
1457static VALID_TYPES: &[&str] = &[
1458 "i8",
1459 "u8",
1460 "i16",
1461 "u16",
1462 "i32",
1463 "u32",
1464 "i64",
1465 "u64",
1466 "i128",
1467 "u128",
1468 "isize",
1469 "usize",
1470 "c_char",
1471 "c_schar",
1472 "c_uchar",
1473 "c_short",
1474 "c_ushort",
1475 "c_int",
1476 "c_uint",
1477 "c_long",
1478 "c_ulong",
1479 "c_longlong",
1480 "c_ulonglong",
1481 "ffi::c_char",
1482 "ffi::c_schar",
1483 "ffi::c_uchar",
1484 "ffi::c_short",
1485 "ffi::c_ushort",
1486 "ffi::c_int",
1487 "ffi::c_uint",
1488 "ffi::c_long",
1489 "ffi::c_ulong",
1490 "ffi::c_longlong",
1491 "ffi::c_ulonglong",
1492 "core::ffi::c_char",
1493 "core::ffi::c_schar",
1494 "core::ffi::c_uchar",
1495 "core::ffi::c_short",
1496 "core::ffi::c_ushort",
1497 "core::ffi::c_int",
1498 "core::ffi::c_uint",
1499 "core::ffi::c_long",
1500 "core::ffi::c_ulong",
1501 "core::ffi::c_longlong",
1502 "core::ffi::c_ulonglong",
1503 "::core::ffi::c_char",
1504 "::core::ffi::c_schar",
1505 "::core::ffi::c_uchar",
1506 "::core::ffi::c_short",
1507 "::core::ffi::c_ushort",
1508 "::core::ffi::c_int",
1509 "::core::ffi::c_uint",
1510 "::core::ffi::c_long",
1511 "::core::ffi::c_ulong",
1512 "::core::ffi::c_longlong",
1513 "::core::ffi::c_ulonglong",
1514 "libc::c_char",
1515 "libc::c_schar",
1516 "libc::c_uchar",
1517 "libc::c_short",
1518 "libc::c_ushort",
1519 "libc::c_int",
1520 "libc::c_uint",
1521 "libc::c_long",
1522 "libc::c_ulong",
1523 "libc::c_longlong",
1524 "libc::c_ulonglong",
1525 "::libc::c_char",
1526 "::libc::c_schar",
1527 "::libc::c_uchar",
1528 "::libc::c_short",
1529 "::libc::c_ushort",
1530 "::libc::c_int",
1531 "::libc::c_uint",
1532 "::libc::c_long",
1533 "::libc::c_ulong",
1534 "::libc::c_longlong",
1535 "::libc::c_ulonglong",
1536 "blkcnt_t",
1537 "blksize_t",
1538 "clock_t",
1539 "clockid_t",
1540 "dev_t",
1541 "fsblkcnt_t",
1542 "fsfilcnt_t",
1543 "gid_t",
1544 "id_t",
1545 "ino_t",
1546 "key_t",
1547 "mode_t",
1548 "nlink_t",
1549 "off_t",
1550 "pid_t",
1551 "size_t",
1552 "ssize_t",
1553 "suseconds_t",
1554 "time_t",
1555 "uid_t",
1556 "libc::blkcnt_t",
1557 "libc::blksize_t",
1558 "libc::clock_t",
1559 "libc::clockid_t",
1560 "libc::dev_t",
1561 "libc::fsblkcnt_t",
1562 "libc::fsfilcnt_t",
1563 "libc::gid_t",
1564 "libc::id_t",
1565 "libc::ino_t",
1566 "libc::key_t",
1567 "libc::mode_t",
1568 "libc::nlink_t",
1569 "libc::off_t",
1570 "libc::pid_t",
1571 "libc::size_t",
1572 "libc::ssize_t",
1573 "libc::suseconds_t",
1574 "libc::time_t",
1575 "libc::uid_t",
1576 "::libc::blkcnt_t",
1577 "::libc::blksize_t",
1578 "::libc::clock_t",
1579 "::libc::clockid_t",
1580 "::libc::dev_t",
1581 "::libc::fsblkcnt_t",
1582 "::libc::fsfilcnt_t",
1583 "::libc::gid_t",
1584 "::libc::id_t",
1585 "::libc::ino_t",
1586 "::libc::key_t",
1587 "::libc::mode_t",
1588 "::libc::nlink_t",
1589 "::libc::off_t",
1590 "::libc::pid_t",
1591 "::libc::size_t",
1592 "::libc::ssize_t",
1593 "::libc::suseconds_t",
1594 "::libc::time_t",
1595 "::libc::uid_t",
1596];