enumset/
traits.rs

1use crate::repr::EnumSetTypeRepr;
2
3#[cfg(feature = "serde")]
4use crate::EnumSet;
5
6/// The trait used to define enum types that may be used with [`EnumSet`].
7///
8/// This trait must be impelmented using `#[derive(EnumSetType)]`, is not public API, and its
9/// internal structure may change at any time with no warning.
10///
11/// For full documentation on the procedural derive and its options, see
12/// [`#[derive(EnumSetType)]`](derive@crate::EnumSetType).
13///
14/// [`EnumSet`]: crate::set::EnumSet
15pub unsafe trait EnumSetType: Copy + Eq + EnumSetTypePrivate {}
16
17/// An [`EnumSetType`] for which [`EnumSet`]s have a guaranteed in-memory representation.
18///
19/// An implementation of this trait is generated by using
20/// [`#[derive(EnumSetType)]`](derive@crate::EnumSetType) with the annotation
21/// `#[enumset(repr = "…")]`, where `…` is `u8`, `u16`, `u32`, `u64` or `u128`.
22///
23/// For any type `T` that implements this trait, the in-memory representation of `EnumSet<T>`
24/// is guaranteed to be `Repr`. This guarantee is useful for FFI. See [the `EnumSet` documentation
25/// under “FFI, Safety and `repr`”][crate::set::EnumSet#ffi-safety-and-repr] for an example.
26///
27/// [`EnumSet`]: crate::set::EnumSet
28pub unsafe trait EnumSetTypeWithRepr:
29    EnumSetType + EnumSetTypePrivate<Repr = <Self as EnumSetTypeWithRepr>::Repr>
30{
31    /// The guaranteed representation.
32    type Repr: EnumSetTypeRepr;
33}
34
35/// The actual members of EnumSetType. Put here to avoid polluting global namespaces.
36pub unsafe trait EnumSetTypePrivate: EnumSetConstHelper + Sized {
37    /// The underlying type used to store the bitset.
38    type Repr: EnumSetTypeRepr;
39    /// A mask of bits that are valid in the bitset.
40    const ALL_BITS: Self::Repr;
41    /// The largest bit used in the bitset.
42    const BIT_WIDTH: u32;
43    /// The number of variants in the bitset.
44    const VARIANT_COUNT: u32;
45
46    /// Converts an enum of this type into its bit position.
47    fn enum_into_u32(self) -> u32;
48
49    /// Converts a bit position into an enum value.
50    unsafe fn enum_from_u32(val: u32) -> Self;
51
52    /// Converts a bit position into an enum value, with an debug_assert.
53    unsafe fn enum_from_u32_checked(val: u32) -> Self {
54        debug_assert!(Self::ALL_BITS.has_bit(val), "Unknown bit retrieved from bitset.");
55        Self::enum_from_u32(val)
56    }
57
58    /// Serializes the `EnumSet`.
59    ///
60    /// This and `deserialize` are part of the `EnumSetType` trait so the procedural derive
61    /// can control how `EnumSet` is serialized.
62    #[cfg(feature = "serde")]
63    fn serialize<S: serde::Serializer>(set: EnumSet<Self>, ser: S) -> Result<S::Ok, S::Error>
64    where Self: EnumSetType;
65    /// Deserializes the `EnumSet`.
66    #[cfg(feature = "serde")]
67    fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<EnumSet<Self>, D::Error>
68    where Self: EnumSetType;
69}
70
71/// Retrieves a helper type for constant time operations on `EnumSet`s.
72pub unsafe trait EnumSetConstHelper {
73    /// A helper type used to convert values to EnumSets at compile-time.
74    type ConstInitHelper;
75    /// The instance of the `ConstInitHelper`.
76    const CONST_INIT_HELPER: Self::ConstInitHelper;
77
78    /// A helper type used to implement compile-time operations on enums.
79    type ConstOpHelper;
80    /// The instance of the `ConstOpHelper`.
81    const CONST_OP_HELPER: Self::ConstOpHelper;
82}