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}