fieldless_enum_tools/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#[cfg(feature = "alloc")]
3extern crate alloc;
4
5/// Adds an function `all` to enum, returning an array with all variants of the enum
6///
7/// ```rust
8/// use fieldless_enum_tools::All;
9///
10/// #[derive(All, Debug, PartialEq, Eq)]
11/// enum CoolEnum {
12///     CoolVariantOne,
13///     CoolVariantTwo
14/// }
15///
16/// assert_eq!(
17///     CoolEnum::all(),
18///     [CoolEnum::CoolVariantOne, CoolEnum::CoolVariantTwo]
19/// );
20/// ```
21///
22/// # Attributes
23///
24/// ## Outer attributes
25///
26/// `#[all_doc = r#"..."#)]`
27///
28/// Sets the doc of the function, with the default being "Returns an array of all elements on this enum."
29pub use fieldless_enum_tools_impl::All;
30
31/// Implements [`Not`] for enum.
32///
33/// ```rust
34/// use fieldless_enum_tools::Not;
35///
36/// // works without any attributes on enum with up to two variants
37/// #[derive(Not, Debug, PartialEq, Eq)]
38/// enum One {
39///     One
40/// }
41///
42/// assert_eq!(!One::One, One::One);
43///
44/// #[derive(Not, Debug, PartialEq, Eq)]
45/// enum More {
46///     One,
47///     Two
48/// }
49///
50/// assert_eq!(!More::One, More::Two);
51/// assert_eq!(!More::Two, More::One);
52///
53/// // requires attributes after
54/// #[derive(Not, Debug, PartialEq, Eq)]
55/// enum Multiple {
56///     #[not(OppositeOfOne)]
57///     One,
58///     #[not(OppositeOfTwo)]
59///     Two,
60///     #[not(One)]
61///     OppositeOfOne,
62///     #[not(Two)]
63///     OppositeOfTwo,
64///     #[not(Trap)]
65///     Trap
66/// }
67///
68/// assert_eq!(!Multiple::One, Multiple::OppositeOfOne);
69/// assert_eq!(!Multiple::OppositeOfTwo, Multiple::Two);
70/// assert_eq!(!Multiple::Trap, Multiple::Trap);
71/// ```
72///
73/// # Attributes
74///
75/// ## Variant attributes
76///
77/// `#[not(...)]`
78///
79/// Specifies which variant this variant will return when [`Not`]'ed
80///
81/// [`Not`]: `core::ops::Not`
82pub use fieldless_enum_tools_impl::Not;
83
84/// Implements
85/// [`AsRef<str>`],
86/// [`Into<String>`][^alloc],
87/// [`Display`] (therefore [`ToString`][^alloc]), [`FromStr`],
88/// [`TryFrom<String>`][^alloc],
89/// [`Serialize`][^serde] and [`Deserialize`][^serde] for enum.
90///
91///```rust
92/// use fieldless_enum_tools::FromToStr;
93///
94/// #[derive(FromToStr, Debug, PartialEq, Eq, Clone, Copy)]
95/// #[fromtostr(format(style = "delimited", separator = "😎"))]
96/// enum CoolEnum {
97///     #[fromtostr(aliases("cool_variant_one"))]
98///     CoolVariantOne,
99///     #[fromtostr(rename("Very😎Cool😎Variant😎Two"))]
100///     CoolVariantTwo
101/// }
102///
103///
104/// let cool = CoolEnum::CoolVariantOne;
105///
106/// assert_eq!(cool.as_ref(), "Cool😎Variant😎One");
107/// assert_eq!("cool_variant_one".parse(), Ok(cool));
108/// assert_eq!("Cool😎Variant😎One".parse(), Ok(cool));
109///
110/// let cool = CoolEnum::CoolVariantTwo;
111/// assert_eq!("Very😎Cool😎Variant😎Two".parse(), Ok(cool));
112///
113/// assert_eq!("uncool variant :(".parse::<CoolEnum>(), Err(()));
114/// // errors because we renamed it to Very😎Cool😎Variant😎Two
115/// assert_eq!("Cool😎Variant😎Two".parse::<CoolEnum>(), Err(()));
116///```
117///
118/// # Attributes
119/// ## Outer attributes
120///
121/// `#[fromtostr(skip(...*))]`
122///
123/// Skips implementing specified traits
124///
125///   **Possible Values**
126///
127/// >| Value           | Skips               |
128/// >|-----------------|---------------------|
129/// >| `TryFromString` | [`TryFrom<String>`] |
130/// >| `FromStr`       | [`FromStr`]         |
131/// >| `AsRefStr`      | [`AsRef<str>`]      |
132/// >| `IntoString`    | [`Into<String>`]    |
133/// >| `Display`       | [`Display`]         |
134/// >| `Serialize`     | [`Serialize`]       |
135/// >| `Deserialize`   | [`Deserialize`]     |
136///
137/// ---
138///
139/// `#[fromtostr(format(style = "...", separator = "..."?))]`
140///
141/// Format variants using specified [style](Self#possible-styles)
142///
143///
144/// ## Variant attributes
145///
146/// `#[fromtostr(aliases("..."*))]`
147///
148/// Specifies one (or more aliases) for this variant
149///
150/// ---
151///
152/// `#[fromtostr(rename("..."))]` or `#[fromtostr(rename(style = "...", separator = "..."?))]`
153///
154/// Renames this variant with specified string or specified [format style](Self#possible-styles)
155///
156/// # Possible Styles
157///
158/// >| Style Name        | Description                                           | Example               | Note                                                    |
159/// >|-------------------|-------------------------------------------------------|-----------------------|---------------------------------------------------------|
160/// >| `none`            | keep it as is                                         | `TwoWords`            |                                                         |
161/// >| `lower`           | to lowercase                                          | `twowords`            |                                                         |
162/// >| `UPPER`           | to uppercase                                          | `TWOWORDS`            |                                                         |
163/// >| `snake`           | to snake case                                         | `two_words`           | alias to `delimitedlower` style with a `_` separator    |
164/// >| `kebab`           | to kebab case                                         | `two-words`           | alias to `delimitedlower` style with a `-` separator    |
165/// >| `SCREAMING_SNAKE` | to screaming snake case                               | `TWO_WORDS`           | alias to `DELIMITEDUPPER` with a `_` separator          |
166/// >| `SCREAMING-KEBAB` | to screaming kebab case                               | `TWO-WORDS`           | alias it to `DELIMITEDUPPER` style with a `-` separator |
167/// >| `camel`           | to camel case                                         | `twoWords`            |                                                         |
168/// >| `camel_Snake`     | to camel snake case                                   | `two_Words`           |                                                         |
169/// >| `Pascal`          | to pascal case                                        | `TwoWords`            |                                                         |
170/// >| `Pascal_Snake`    | to pascal snake case                                  | `Two_Words`           |                                                         |
171/// >| `Train`           | to train case                                         | `Two-Words`           |                                                         |
172/// >| `delimited`       | delimits every word with separator                    | `Two{separator}Words` | needs to specify a separator value                      |
173/// >| `delimitedlower`  | delimits every word with separator, then to lowercase | `two{separator}words` | needs to specify a separator value                      |
174/// >| `DELIMITEDUPPER`  | delimits every word with separator, then to uppercase | `TWO{SEPARATOR}WORDS` | needs to specify a separator value                      |
175
176///
177/// [^alloc]: if crate feature `std` or `alloc` avaliable.
178///
179/// [^serde]: if crate feature `serde` avaliable.
180///
181/// [`Display`]: `core::fmt::Display`
182/// [`TryFrom<String>`]: `core::convert::TryFrom`
183/// [`FromStr`]: `core::str::FromStr`
184/// [`Serialize`]: https://serde.rs/
185/// [`Deserialize`]: https://serde.rs/
186pub use fieldless_enum_tools_impl::FromToStr;
187
188#[cfg(not(doc))]
189pub mod __internal {
190    #[cfg(all(feature = "alloc", not(feature = "std")))]
191    pub use alloc::string::String;
192    #[cfg(feature = "std")]
193    pub use std::string::String;
194
195    #[cfg(feature = "serde")]
196    pub use serde;
197
198    #[cfg(not(feature = "serde"))]
199    #[macro_export]
200    macro_rules! if_serde_enabled {
201        ($($t:tt)*) => {};
202    }
203
204    #[cfg(feature = "serde")]
205    #[macro_export]
206    macro_rules! if_serde_enabled {
207        ($($t:tt)*) => { $($t)* };
208    }
209
210    #[cfg(not(any(feature = "alloc", feature = "std")))]
211    #[macro_export]
212    macro_rules! if_alloc_enabled {
213        ($($t:tt)*) => {};
214    }
215
216    #[cfg(any(feature = "alloc", feature = "std"))]
217    #[macro_export]
218    macro_rules! if_alloc_enabled {
219        ($($t:tt)*) => { $($t)* };
220    }
221
222    #[cfg(not(feature = "std"))]
223    #[macro_export]
224    macro_rules! if_std_enabled {
225        ($($t:tt)*) => {};
226    }
227
228    #[cfg(feature = "std")]
229    #[macro_export]
230    macro_rules! if_std_enabled {
231        ($($t:tt)*) => { $($t)* };
232    }
233}