#[darling(attributes(enumset), default)]
struct EnumsetAttrs {
no_ops: bool,
+ no_super_impls: bool,
serialize_as_list: bool,
serialize_deny_unknown: bool,
#[darling(default)]
/// Avoid generating operator overloads on the enum type.
no_ops: bool,
+ /// Avoid generating implementations for `Clone`, `Copy`, `Eq`, and `PartialEq`.
+ no_super_impls: bool,
/// Serialize the enum as a list.
serialize_as_list: bool,
/// Disallow unknown bits while deserializing the enum.
used_variant_names: HashSet::new(),
used_discriminants: HashSet::new(),
no_ops: attrs.no_ops,
+ no_super_impls: attrs.no_super_impls,
serialize_as_list: attrs.serialize_as_list,
serialize_deny_unknown: attrs.serialize_deny_unknown
}
fn serialize<S: #serde::Serializer>(
set: #enumset::EnumSet<#name>, ser: S,
) -> #core::result::Result<S::Ok, S::Error> {
- #serde::Serialize::serialize(&(set.__enumset_underlying as #serialize_repr), ser)
+ #serde::Serialize::serialize(&(set.__priv_repr as #serialize_repr), ser)
}
fn deserialize<'de, D: #serde::Deserializer<'de>>(
de: D,
let value = <#serialize_repr as #serde::Deserialize>::deserialize(de)?;
#check_unknown
#core::prelude::v1::Ok(#enumset::EnumSet {
- __enumset_underlying: (value & #all_variants) as #repr,
+ __priv_repr: (value & #all_variants) as #repr,
})
}
}
quote!((*self as u32) == (*other as u32))
};
+ // used in the enum_set! macro `const fn`s.
+ let self_as_repr_mask = if is_uninhabited {
+ quote! { 0 } // impossible anyway
+ } else {
+ quote! { 1 << self as #repr }
+ };
+
+ let super_impls = if info.no_super_impls {
+ quote! {}
+ } else {
+ quote! {
+ impl #core::cmp::PartialEq for #name {
+ fn eq(&self, other: &Self) -> bool {
+ #eq_impl
+ }
+ }
+ impl #core::cmp::Eq for #name { }
+ #[allow(clippy::expl_impl_clone_on_copy)]
+ impl #core::clone::Clone for #name {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ impl #core::marker::Copy for #name { }
+ }
+ };
+
quote! {
unsafe impl #enumset::__internal::EnumSetTypePrivate for #name {
type Repr = #repr;
unsafe impl #enumset::EnumSetType for #name { }
- impl #core::cmp::PartialEq for #name {
- fn eq(&self, other: &Self) -> bool {
- #eq_impl
+ #super_impls
+
+ impl #name {
+ /// Creates a new enumset with only this variant.
+ #[deprecated(note = "This method is an internal implementation detail generated by \
+ the `enumset` crate's procedural macro. It should not be used \
+ directly. Use `EnumSet::only` instead.")]
+ #[doc(hidden)]
+ pub const fn __impl_enumset_internal__const_only(self) -> #enumset::EnumSet<#name> {
+ #enumset::EnumSet { __priv_repr: #self_as_repr_mask }
}
- }
- impl #core::cmp::Eq for #name { }
- impl #core::clone::Clone for #name {
- fn clone(&self) -> Self {
- *self
+
+ /// Creates a new enumset with this variant added.
+ #[deprecated(note = "This method is an internal implementation detail generated by \
+ the `enumset` crate's procedural macro. It should not be used \
+ directly. Use the `|` operator instead.")]
+ #[doc(hidden)]
+ pub const fn __impl_enumset_internal__const_merge(
+ self, chain: #enumset::EnumSet<#name>,
+ ) -> #enumset::EnumSet<#name> {
+ #enumset::EnumSet { __priv_repr: chain.__priv_repr | #self_as_repr_mask }
}
}
- impl #core::marker::Copy for #name { }
#ops
}
}
-/// A wrapper that parses the input enum.
#[proc_macro_derive(EnumSetType, attributes(enumset))]
pub fn derive_enum_set_type(input: TokenStream) -> TokenStream {
let input: DeriveInput = parse_macro_input!(input);