@@ -667,6 +667,33 @@ where
667
667
unsafe { BitFlags :: from_bits_unchecked ( bits & T :: ALL_BITS ) }
668
668
}
669
669
670
+ /// Validate if an underlying bitwise value can safely be converted to `BitFlags`.
671
+ /// Returns false if any invalid bits are set.
672
+ ///
673
+ /// ```
674
+ /// # use enumflags2::{bitflags, BitFlags};
675
+ /// #[bitflags]
676
+ /// #[repr(u8)]
677
+ /// #[derive(Clone, Copy, PartialEq, Eq)]
678
+ /// enum MyFlag {
679
+ /// One = 0b0001,
680
+ /// Two = 0b0010,
681
+ /// Three = 0b1000,
682
+ /// }
683
+ ///
684
+ /// assert_eq!(BitFlags::<MyFlag>::validate_bits(0b1011), true);
685
+ /// assert_eq!(BitFlags::<MyFlag>::validate_bits(0b0000), true);
686
+ /// assert_eq!(BitFlags::<MyFlag>::validate_bits(0b0100), false);
687
+ /// assert_eq!(BitFlags::<MyFlag>::validate_bits(0b1111), false);
688
+ /// ```
689
+ #[ must_use]
690
+ #[ inline( always) ]
691
+ pub fn validate_bits ( bits : T :: Numeric ) -> bool {
692
+ // SAFETY: We're truncating out all the invalid bits so it will
693
+ // only be different if there are invalid bits set.
694
+ ( bits & T :: ALL_BITS ) == bits
695
+ }
696
+
670
697
/// Create a new BitFlags unsafely, without checking if the bits form
671
698
/// a valid bit pattern for the type.
672
699
///
@@ -1102,8 +1129,11 @@ mod impl_zerocopy {
1102
1129
let my_candidate =
1103
1130
unsafe { candidate. assume_validity :: < zerocopy:: pointer:: invariant:: Valid > ( ) } ;
1104
1131
{
1105
- ( my_candidate. read_unaligned :: < zerocopy:: pointer:: BecauseImmutable > ( ) ^ T :: ALL_BITS )
1106
- == T :: EMPTY
1132
+ // TODO: Currently this assumes that the candidate is aligned. We actually need to check this beforehand
1133
+ // Dereference the pointer to the candidate
1134
+ let candidate =
1135
+ my_candidate. read_unaligned :: < zerocopy:: pointer:: BecauseImmutable > ( ) ;
1136
+ return BitFlags :: < T > :: validate_bits ( candidate) ;
1107
1137
}
1108
1138
}
1109
1139
}
0 commit comments