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 {}