@@ -667,6 +667,33 @@ where
667667 unsafe { BitFlags :: from_bits_unchecked ( bits & T :: ALL_BITS ) }
668668 }
669669
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+
670697 /// Create a new BitFlags unsafely, without checking if the bits form
671698 /// a valid bit pattern for the type.
672699 ///
@@ -1102,8 +1129,11 @@ mod impl_zerocopy {
11021129 let my_candidate =
11031130 unsafe { candidate. assume_validity :: < zerocopy:: pointer:: invariant:: Valid > ( ) } ;
11041131 {
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) ;
11071137 }
11081138 }
11091139 }
0 commit comments