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
34/// Helper macro to create a new enum type with a single field.
35///
36/// The enum type is derived with the `Clone`, `Copy`, `PartialEq`, `Eq`,
37/// `PartialOrd`, `Ord`, and `Hash` traits. The nutype also impls `From` and
38/// `Into` for the underlying type. As well as a custom `Debug` impl for human
39/// readable output.
40///
41/// # Examples
42///
43/// ```rust
44/// # use nutype_enum::nutype_enum;
45/// nutype_enum! {
46/// pub enum AacPacketType(u8) {
47/// SeqHdr = 0x0,
48/// Raw = 0x1,
49/// }
50/// }
51/// ```
52#[macro_export]
53macro_rules! nutype_enum {
54 (
55 $(#[$attr:meta])*
56 $vis:vis enum $name:ident($type:ty) {
57 $(
58 $(#[$variant_attr:meta])*
59 $variant:ident = $value:expr
60 ),*$(,)?
61 }
62 ) => {
63 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
64 $(#[$attr])*
65 #[repr(transparent)]
66 $vis struct $name(pub $type);
67
68 impl ::std::fmt::Debug for $name {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 match self {
71 $(
72 &$name::$variant => write!(f, "{}::{}", stringify!($name), stringify!($variant)),
73 )*
74 _ => write!(f, "{}({:?})", stringify!($name), self.0),
75 }
76 }
77 }
78
79 impl $name {
80 $(
81 $(#[$variant_attr])*
82 #[allow(non_upper_case_globals)]
83 pub const $variant: Self = Self($value);
84 )*
85 }
86
87 impl From<$type> for $name {
88 fn from(value: $type) -> Self {
89 Self(value)
90 }
91 }
92
93 impl From<$name> for $type {
94 fn from(value: $name) -> Self {
95 value.0
96 }
97 }
98 };
99}
100
101/// Helper macro to create a bitwise enum.
102///
103/// The enum type is derived with the `BitAnd`, `BitOr`, `BitXor`, `BitAndAssign`,
104/// `BitOrAssign`, and `BitXorAssign` traits.
105///
106/// # Examples
107///
108/// ```rust
109/// # use nutype_enum::{nutype_enum, bitwise_enum};
110/// nutype_enum! {
111/// pub enum IoFlags(u8) {
112/// Seek = 0x1,
113/// Write = 0x2,
114/// Read = 0x4,
115/// }
116/// }
117///
118/// bitwise_enum!(IoFlags);
119/// ```
120#[macro_export]
121macro_rules! bitwise_enum {
122 ($name:ident) => {
123 impl ::std::ops::BitAnd for $name {
124 type Output = Self;
125
126 fn bitand(self, rhs: Self) -> Self::Output {
127 Self(self.0 & rhs.0)
128 }
129 }
130
131 impl ::std::ops::BitOr for $name {
132 type Output = Self;
133
134 fn bitor(self, rhs: Self) -> Self::Output {
135 Self(self.0 | rhs.0)
136 }
137 }
138
139 impl ::std::ops::BitXor for $name {
140 type Output = Self;
141
142 fn bitxor(self, rhs: Self) -> Self::Output {
143 Self(self.0 ^ rhs.0)
144 }
145 }
146
147 impl ::std::ops::Not for $name {
148 type Output = Self;
149
150 fn not(self) -> Self::Output {
151 Self(!self.0)
152 }
153 }
154
155 impl ::std::ops::BitAndAssign for $name {
156 fn bitand_assign(&mut self, rhs: Self) {
157 self.0 &= rhs.0;
158 }
159 }
160
161 impl ::std::ops::BitOrAssign for $name {
162 fn bitor_assign(&mut self, rhs: Self) {
163 self.0 |= rhs.0;
164 }
165 }
166
167 impl ::std::ops::BitXorAssign for $name {
168 fn bitxor_assign(&mut self, rhs: Self) {
169 self.0 ^= rhs.0;
170 }
171 }
172 };
173}
174
175// /// XD
176// pub mod xd {}
177
178/// Changelogs generated by [scuffle_changelog]
179#[cfg(feature = "docs")]
180#[scuffle_changelog::changelog]
181pub mod changelog {}