nutype_enum/
lib.rs

1//! The crate provides a macro to create a new enum type with a single field.
2#![cfg_attr(feature = "docs", doc = "\n\nSee the [changelog][changelog] for a full release history.")]
3#![cfg_attr(feature = "docs", doc = "## Feature flags")]
4#![cfg_attr(feature = "docs", doc = document_features::document_features!())]
5//! ## Why do we need this?
6//!
7//! This is useful when you have a value and you want to have enum like behavior and have a catch all case for all other values.
8//!
9//! ## Examples
10//!
11//! ```rust
12//! use nutype_enum::nutype_enum;
13//!
14//! nutype_enum! {
15//!     pub enum AacPacketType(u8) {
16//!         SeqHdr = 0x0,
17//!         Raw = 0x1,
18//!     }
19//! }
20//! ```
21//!
22//! ## License
23//!
24//! This project is licensed under the MIT or Apache-2.0 license.
25//! You can choose between one of them if you use this work.
26//!
27//! `SPDX-License-Identifier: MIT OR Apache-2.0`
28#![cfg_attr(all(coverage_nightly, test), feature(coverage_attribute))]
29#![cfg_attr(docsrs, feature(doc_auto_cfg))]
30#![deny(missing_docs)]
31#![deny(unsafe_code)]
32#![deny(unreachable_pub)]
33#![deny(clippy::mod_module_files)]
34
35/// Helper macro to create a new enum type with a single field.
36///
37/// The enum type is derived with the `Clone`, `Copy`, `PartialEq`, `Eq`,
38/// `PartialOrd`, `Ord`, and `Hash` traits. The nutype also impls `From` and
39/// `Into` for the underlying type. As well as a custom `Debug` impl for human
40/// readable output.
41///
42/// # Examples
43///
44/// ```rust
45/// # use nutype_enum::nutype_enum;
46/// nutype_enum! {
47///     pub enum AacPacketType(u8) {
48///         SeqHdr = 0x0,
49///         Raw = 0x1,
50///     }
51/// }
52/// ```
53#[macro_export]
54macro_rules! nutype_enum {
55    (
56        $(#[$attr:meta])*
57        $vis:vis enum $name:ident($type:ty) {
58            $(
59                $(#[$variant_attr:meta])*
60                $variant:ident = $value:expr
61            ),*$(,)?
62        }
63    ) => {
64        #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
65        $(#[$attr])*
66        #[repr(transparent)]
67        $vis struct $name(pub $type);
68
69        impl ::std::fmt::Debug for $name {
70            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71                match self {
72                    $(
73                        &$name::$variant => write!(f, "{}::{}", stringify!($name), stringify!($variant)),
74                    )*
75                    _ => write!(f, "{}({:?})", stringify!($name), self.0),
76                }
77            }
78        }
79
80        impl $name {
81            $(
82                $(#[$variant_attr])*
83                #[allow(non_upper_case_globals)]
84                pub const $variant: Self = Self($value);
85            )*
86        }
87
88        impl From<$type> for $name {
89            fn from(value: $type) -> Self {
90                Self(value)
91            }
92        }
93
94        impl From<$name> for $type {
95            fn from(value: $name) -> Self {
96                value.0
97            }
98        }
99    };
100}
101
102/// Helper macro to create a bitwise enum.
103///
104/// The enum type is derived with the `BitAnd`, `BitOr`, `BitXor`, `BitAndAssign`,
105/// `BitOrAssign`, and `BitXorAssign` traits.
106///
107/// # Examples
108///
109/// ```rust
110/// # use nutype_enum::{nutype_enum, bitwise_enum};
111/// nutype_enum! {
112///     pub enum IoFlags(u8) {
113///         Seek = 0x1,
114///         Write = 0x2,
115///         Read = 0x4,
116///     }
117/// }
118///
119/// bitwise_enum!(IoFlags);
120/// ```
121#[macro_export]
122macro_rules! bitwise_enum {
123    ($name:ident) => {
124        impl ::std::ops::BitAnd for $name {
125            type Output = Self;
126
127            fn bitand(self, rhs: Self) -> Self::Output {
128                Self(self.0 & rhs.0)
129            }
130        }
131
132        impl ::std::ops::BitOr for $name {
133            type Output = Self;
134
135            fn bitor(self, rhs: Self) -> Self::Output {
136                Self(self.0 | rhs.0)
137            }
138        }
139
140        impl ::std::ops::BitXor for $name {
141            type Output = Self;
142
143            fn bitxor(self, rhs: Self) -> Self::Output {
144                Self(self.0 ^ rhs.0)
145            }
146        }
147
148        impl ::std::ops::Not for $name {
149            type Output = Self;
150
151            fn not(self) -> Self::Output {
152                Self(!self.0)
153            }
154        }
155
156        impl ::std::ops::BitAndAssign for $name {
157            fn bitand_assign(&mut self, rhs: Self) {
158                self.0 &= rhs.0;
159            }
160        }
161
162        impl ::std::ops::BitOrAssign for $name {
163            fn bitor_assign(&mut self, rhs: Self) {
164                self.0 |= rhs.0;
165            }
166        }
167
168        impl ::std::ops::BitXorAssign for $name {
169            fn bitxor_assign(&mut self, rhs: Self) {
170                self.0 ^= rhs.0;
171            }
172        }
173    };
174}
175
176// /// XD
177// pub mod xd {}
178
179/// Changelogs generated by [scuffle_changelog]
180#[cfg(feature = "docs")]
181#[scuffle_changelog::changelog]
182pub mod changelog {}