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