mirror of
https://github.com/danog/strum.git
synced 2024-11-26 20:14:40 +01:00
Wiki to doc tests (#121)
* example usage as doctests added to the strum_macros crate * removed links to to wiki example code and documentation of the macros * added attribute documentation as a module in strum and linked to it
This commit is contained in:
parent
7e64a470b1
commit
89b9c14731
68
strum/src/additional_attributes.rs
Normal file
68
strum/src/additional_attributes.rs
Normal file
@ -0,0 +1,68 @@
|
||||
//! # Documentation for Additional Attributes
|
||||
//!
|
||||
//! Strum supports several custom attributes to modify the generated code. At the enum level, the
|
||||
//! `#[strum(serialize_all = "snake_case")]` attribute can be used to change the case used when
|
||||
//! serializing to and deserializing from strings:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use std::string::ToString;
|
||||
//! use strum;
|
||||
//! use strum_macros;
|
||||
//!
|
||||
//! #[derive(Debug, Eq, PartialEq, strum_macros::ToString)]
|
||||
//! #[strum(serialize_all = "snake_case")]
|
||||
//! enum Brightness {
|
||||
//! DarkBlack,
|
||||
//! Dim {
|
||||
//! glow: usize,
|
||||
//! },
|
||||
//! #[strum(serialize = "bright")]
|
||||
//! BrightWhite,
|
||||
//! }
|
||||
//!
|
||||
//! assert_eq!(
|
||||
//! String::from("dark_black"),
|
||||
//! Brightness::DarkBlack.to_string().as_ref()
|
||||
//! );
|
||||
//! assert_eq!(
|
||||
//! String::from("dim"),
|
||||
//! Brightness::Dim { glow: 0 }.to_string().as_ref()
|
||||
//! );
|
||||
//! assert_eq!(
|
||||
//! String::from("bright"),
|
||||
//! Brightness::BrightWhite.to_string().as_ref()
|
||||
//! );
|
||||
//! ```
|
||||
//!
|
||||
//! Custom attributes are applied to a variant by adding `#[strum(parameter="value")]` to the variant.
|
||||
//!
|
||||
//! - `serialize="..."`: Changes the text that `FromStr()` looks for when parsing a string. This attribute can
|
||||
//! be applied multiple times to an element and the enum variant will be parsed if any of them match.
|
||||
//!
|
||||
//! - `to_string="..."`: Similar to `serialize`. This value will be included when using `FromStr()`. More importantly,
|
||||
//! this specifies what text to use when calling `variant.to_string()` with the `ToString` derivation, or when calling `variant.as_ref()` with `AsRefStr`.
|
||||
//!
|
||||
//! - `default`: Applied to a single variant of an enum. The variant must be a Tuple-like
|
||||
//! variant with a single piece of data that can be create from a `&str` i.e. `T: From<&str>`.
|
||||
//! The generated code will now return the variant with the input string captured as shown below
|
||||
//! instead of failing.
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
//! // Replaces this:
|
||||
//! _ => Err(strum::ParseError::VariantNotFound)
|
||||
//! // With this in generated code:
|
||||
//! default => Ok(Variant(default.into()))
|
||||
//! ```
|
||||
//! The plugin will fail if the data doesn't implement From<&str>. You can only have one `default`
|
||||
//! on your enum.
|
||||
//!
|
||||
//! - `disabled`: removes variant from generated code.
|
||||
//!
|
||||
//! - `message=".."`: Adds a message to enum variant. This is used in conjunction with the `EnumMessage`
|
||||
//! trait to associate a message with a variant. If `detailed_message` is not provided,
|
||||
//! then `message` will also be returned when get_detailed_message() is called.
|
||||
//!
|
||||
//! - `detailed_message=".."`: Adds a more detailed message to a variant. If this value is omitted, then
|
||||
//! `message` will be used in it's place.
|
||||
//!
|
||||
//! - `props(key="value")`: Enables associating additional information with a given variant.
|
@ -20,33 +20,9 @@
|
||||
//! strum_macros = "0.18.0"
|
||||
//! ```
|
||||
//!
|
||||
//! # Strum Macros
|
||||
//!
|
||||
//! Strum has implemented the following macros:
|
||||
//!
|
||||
//! | Macro | Description |
|
||||
//! | --- | ----------- |
|
||||
//! | [EnumString] | Converts strings to enum variants based on their name |
|
||||
//! | [Display] | Converts enum variants to strings |
|
||||
//! | [AsRefStr] | Converts enum variants to `&'static str` |
|
||||
//! | [IntoStaticStr] | Implements `From<MyEnum> for &'static str` on an enum |
|
||||
//! | [EnumVariantNames] | Implements Strum::VariantNames which adds an associated constant `VARIANTS` which is an array of discriminant names |
|
||||
//! | [EnumIter] | Creates a new type that iterates of the variants of an enum. |
|
||||
//! | [EnumProperty] | Add custom properties to enum variants. |
|
||||
//! | [EnumMessage] | Add a verbose message to an enum variant. |
|
||||
//! | [EnumDiscriminants] | Generate a new type with only the discriminant names. |
|
||||
//! | [EnumCount] | Add a constant `usize` equal to the number of variants. |
|
||||
//!
|
||||
//! [EnumString]: https://github.com/Peternator7/strum/wiki/Derive-EnumString
|
||||
//! [Display]: https://github.com/Peternator7/strum/wiki/Derive-Display
|
||||
//! [AsRefStr]: https://github.com/Peternator7/strum/wiki/Derive-AsRefStr
|
||||
//! [IntoStaticStr]: https://github.com/Peternator7/strum/wiki/Derive-IntoStaticStr
|
||||
//! [EnumVariantNames]: https://github.com/Peternator7/strum/wiki/Derive-EnumVariantNames
|
||||
//! [EnumIter]: https://github.com/Peternator7/strum/wiki/Derive-EnumIter
|
||||
//! [EnumProperty]: https://github.com/Peternator7/strum/wiki/Derive-EnumProperty
|
||||
//! [EnumMessage]: https://github.com/Peternator7/strum/wiki/Derive-EnumMessage
|
||||
//! [EnumDiscriminants]: https://github.com/Peternator7/strum/wiki/Derive-EnumDiscriminants
|
||||
//! [EnumCount]: https://github.com/Peternator7/strum/wiki/Derive-EnumCount
|
||||
|
||||
// only for documentation purposes
|
||||
pub mod additional_attributes;
|
||||
|
||||
/// The ParseError enum is a collection of all the possible reasons
|
||||
/// an enum can fail to parse from a string.
|
||||
@ -204,5 +180,4 @@ pub trait VariantNames {
|
||||
}
|
||||
|
||||
#[cfg(feature = "derive")]
|
||||
#[doc(hidden)]
|
||||
pub use strum_macros::*;
|
||||
|
@ -24,6 +24,9 @@ proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0", features = ["parsing", "extra-traits"] }
|
||||
|
||||
[dev-dependencies]
|
||||
strum = "0.19"
|
||||
|
||||
[features]
|
||||
verbose-enumstring-name = []
|
||||
verbose-asrefstr-name = []
|
||||
|
@ -3,9 +3,6 @@
|
||||
//! Strum is a set of macros and traits for working with
|
||||
//! enums and strings easier in Rust.
|
||||
//!
|
||||
//! # Documentation
|
||||
//!
|
||||
//! The documentation for this crate is found in the `strum` crate.
|
||||
|
||||
#![recursion_limit = "128"]
|
||||
|
||||
@ -30,6 +27,74 @@ fn debug_print_generated(ast: &syn::DeriveInput, toks: &TokenStream) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts strings to enum variants based on their name.
|
||||
///
|
||||
/// auto-derives `std::str::FromStr` on the enum. Each variant of the enum will match on it's own name.
|
||||
/// This can be overridden using `serialize="DifferentName"` or `to_string="DifferentName"`
|
||||
/// on the attribute as shown below.
|
||||
/// Multiple deserializations can be added to the same variant. If the variant contains additional data,
|
||||
/// they will be set to their default values upon deserialization.
|
||||
///
|
||||
/// The `default` attribute can be applied to a tuple variant with a single data parameter. When a match isn't
|
||||
/// found, the given variant will be returned and the input string will be captured in the parameter.
|
||||
///
|
||||
/// Note that the implementation of `FromStr` by default only matches on the name of the
|
||||
/// variant. There is an option to match on different case conversions through the
|
||||
/// `#[strum(serialize_all = "snake_case")]` type attribute.
|
||||
///
|
||||
/// See the [Additional Attributes](../strum/additional_attributes/index.html)
|
||||
/// Section for more information on using this feature.
|
||||
///
|
||||
/// # Example howto use EnumString
|
||||
/// ```
|
||||
/// use std::str::FromStr;
|
||||
/// use strum_macros::EnumString;
|
||||
///
|
||||
/// #[derive(Debug, PartialEq, EnumString)]
|
||||
/// enum Color {
|
||||
/// Red,
|
||||
/// // The Default value will be inserted into range if we match "Green".
|
||||
/// Green {
|
||||
/// range: usize,
|
||||
/// },
|
||||
///
|
||||
/// // We can match on multiple different patterns.
|
||||
/// #[strum(serialize = "blue", serialize = "b")]
|
||||
/// Blue(usize),
|
||||
///
|
||||
/// // Notice that we can disable certain variants from being found
|
||||
/// #[strum(disabled)]
|
||||
/// Yellow,
|
||||
/// }
|
||||
///
|
||||
/// /*
|
||||
/// //The generated code will look like:
|
||||
/// impl std::str::FromStr for Color {
|
||||
/// type Err = ::strum::ParseError;
|
||||
///
|
||||
/// fn from_str(s: &str) -> ::std::result::Result<Color, Self::Err> {
|
||||
/// match s {
|
||||
/// "Red" => ::std::result::Result::Ok(Color::Red),
|
||||
/// "Green" => ::std::result::Result::Ok(Color::Green { range:Default::default() }),
|
||||
/// "blue" | "b" => ::std::result::Result::Ok(Color::Blue(Default::default())),
|
||||
/// _ => ::std::result::Result::Err(::strum::ParseError::VariantNotFound),
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// */
|
||||
///
|
||||
/// // simple from string
|
||||
/// let color_variant = Color::from_str("Red").unwrap();
|
||||
/// assert_eq!(Color::Red, color_variant);
|
||||
/// // short version works too
|
||||
/// let color_variant = Color::from_str("b").unwrap();
|
||||
/// assert_eq!(Color::Blue(0), color_variant);
|
||||
/// // was disabled for parsing = returns parse-error
|
||||
/// let color_variant = Color::from_str("Yellow");
|
||||
/// assert!(color_variant.is_err());
|
||||
/// // however the variant is still normally usable
|
||||
/// println!("{:?}", Color::Yellow);
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
not(feature = "verbose-enumstring-name"),
|
||||
proc_macro_derive(EnumString, attributes(strum))
|
||||
@ -46,6 +111,43 @@ pub fn from_string(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Converts enum variants to `&'static str`.
|
||||
///
|
||||
/// Implements `AsRef<str>` on your enum using the same rules as
|
||||
/// `Display` for determining what string is returned. The difference is that `as_ref()` returns
|
||||
/// a `&str` instead of a `String` so you don't allocate any additional memory with each call.
|
||||
///
|
||||
/// ```
|
||||
/// // You need to bring the AsRef trait into scope to use it
|
||||
/// use std::convert::AsRef;
|
||||
/// use strum_macros::AsRefStr;
|
||||
///
|
||||
/// #[derive(AsRefStr, Debug)]
|
||||
/// enum Color {
|
||||
/// #[strum(serialize = "redred")]
|
||||
/// Red,
|
||||
/// Green {
|
||||
/// range: usize,
|
||||
/// },
|
||||
/// Blue(usize),
|
||||
/// Yellow,
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// // uses the serialize string for Display
|
||||
/// let red = Color::Red;
|
||||
/// assert_eq!("redred", red.as_ref());
|
||||
/// // by default the variants Name
|
||||
/// let yellow = Color::Yellow;
|
||||
/// assert_eq!("Yellow", yellow.as_ref());
|
||||
/// // or for string formatting
|
||||
/// println!(
|
||||
/// "blue: {} green: {}",
|
||||
/// Color::Blue(10).as_ref(),
|
||||
/// Color::Green { range: 42 }.as_ref()
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
not(feature = "verbose-asrefstr-name"),
|
||||
proc_macro_derive(AsRefStr, attributes(strum))
|
||||
@ -62,6 +164,27 @@ pub fn as_ref_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Implements Strum::VariantNames which adds an associated constant `VARIANTS` which is an array of discriminant names.
|
||||
///
|
||||
/// Adds an `impl` block for the `enum` that adds a static `VARIANTS` array of `&'static str` that are the discriminant names.
|
||||
/// This will respect the `serialize_all` attribute on the `enum` (like `#[strum(serialize_all = "snake_case")]`.
|
||||
///
|
||||
/// ```
|
||||
/// // import the macros needed
|
||||
/// use strum_macros::{EnumString, EnumVariantNames};
|
||||
/// // You need to import the trait, to have access to VARIANTS
|
||||
/// use strum::VariantNames;
|
||||
///
|
||||
/// #[derive(Debug, EnumString, EnumVariantNames)]
|
||||
/// #[strum(serialize_all = "kebab_case")]
|
||||
/// enum Color {
|
||||
/// Red,
|
||||
/// Blue,
|
||||
/// Yellow,
|
||||
/// RebeccaPurple,
|
||||
/// }
|
||||
/// assert_eq!(["red", "blue", "yellow", "rebecca-purple"], Color::VARIANTS);
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
not(feature = "verbose-variant-names"),
|
||||
proc_macro_derive(EnumVariantNames, attributes(strum))
|
||||
@ -97,6 +220,35 @@ pub fn as_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Implements `From<MyEnum> for &'static str` on an enum.
|
||||
///
|
||||
/// Implements `From<YourEnum>` and `From<&'a YourEnum>` for `&'static str`. This is
|
||||
/// useful for turning an enum variant into a static string.
|
||||
/// The Rust `std` provides a blanket impl of the reverse direction - i.e. `impl Into<&'static str> for YourEnum`.
|
||||
///
|
||||
/// ```
|
||||
/// use strum_macros::IntoStaticStr;
|
||||
///
|
||||
/// #[derive(IntoStaticStr)]
|
||||
/// enum State<'a> {
|
||||
/// Initial(&'a str),
|
||||
/// Finished,
|
||||
/// }
|
||||
///
|
||||
/// fn verify_state<'a>(s: &'a str) {
|
||||
/// let mut state = State::Initial(s);
|
||||
/// // The following won't work because the lifetime is incorrect:
|
||||
/// // let wrong: &'static str = state.as_ref();
|
||||
/// // using the trait implemented by the derive works however:
|
||||
/// let right: &'static str = state.into();
|
||||
/// assert_eq!("Initial", right);
|
||||
/// state = State::Finished;
|
||||
/// let done: &'static str = state.into();
|
||||
/// assert_eq!("Finished", done);
|
||||
/// }
|
||||
///
|
||||
/// verify_state(&"hello world".to_string());
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "verbose-intostaticstr-name",
|
||||
proc_macro_derive(StrumIntoStaticStr, attributes(strum))
|
||||
@ -116,6 +268,31 @@ pub fn into_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// implements `std::string::ToString` on en enum
|
||||
///
|
||||
/// ```
|
||||
/// // You need to bring the ToString trait into scope to use it
|
||||
/// use std::string::ToString;
|
||||
/// use strum_macros;
|
||||
///
|
||||
/// #[derive(strum_macros::ToString, Debug)]
|
||||
/// enum Color {
|
||||
/// #[strum(serialize = "redred")]
|
||||
/// Red,
|
||||
/// Green {
|
||||
/// range: usize,
|
||||
/// },
|
||||
/// Blue(usize),
|
||||
/// Yellow,
|
||||
/// }
|
||||
///
|
||||
/// // uses the serialize string for Display
|
||||
/// let red = Color::Red;
|
||||
/// assert_eq!(String::from("redred"), red.to_string());
|
||||
/// // by default the variants Name
|
||||
/// let yellow = Color::Yellow;
|
||||
/// assert_eq!(String::from("Yellow"), yellow.to_string());
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "verbose-tostring-name",
|
||||
proc_macro_derive(StrumToString, attributes(strum))
|
||||
@ -132,6 +309,46 @@ pub fn to_string(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Converts enum variants to strings.
|
||||
///
|
||||
/// Deriving `Display` on an enum prints out the given enum. This enables you to perform round
|
||||
/// trip style conversions from enum into string and back again for unit style variants. `Display`
|
||||
/// choose which serialization to used based on the following criteria:
|
||||
///
|
||||
/// 1. If there is a `to_string` property, this value will be used. There can only be one per variant.
|
||||
/// 1. Of the various `serialize` properties, the value with the longest length is chosen. If that
|
||||
/// behavior isn't desired, you should use `to_string`.
|
||||
/// 1. The name of the variant will be used if there are no `serialize` or `to_string` attributes.
|
||||
///
|
||||
/// ```
|
||||
/// // You need to bring the ToString trait into scope to use it
|
||||
/// use std::string::ToString;
|
||||
/// use strum_macros::Display;
|
||||
///
|
||||
/// #[derive(Display, Debug)]
|
||||
/// enum Color {
|
||||
/// #[strum(serialize = "redred")]
|
||||
/// Red,
|
||||
/// Green {
|
||||
/// range: usize,
|
||||
/// },
|
||||
/// Blue(usize),
|
||||
/// Yellow,
|
||||
/// }
|
||||
///
|
||||
/// // uses the serialize string for Display
|
||||
/// let red = Color::Red;
|
||||
/// assert_eq!(String::from("redred"), format!("{}", red));
|
||||
/// // by default the variants Name
|
||||
/// let yellow = Color::Yellow;
|
||||
/// assert_eq!(String::from("Yellow"), yellow.to_string());
|
||||
/// // or for string formatting
|
||||
/// println!(
|
||||
/// "blue: {} green: {}",
|
||||
/// Color::Blue(10),
|
||||
/// Color::Green { range: 42 }
|
||||
/// );
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "verbose-display-name",
|
||||
proc_macro_derive(StrumDisplay, attributes(strum))
|
||||
@ -148,6 +365,39 @@ pub fn display(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Creates a new type that iterates of the variants of an enum.
|
||||
///
|
||||
/// Iterate over the variants of an Enum. Any additional data on your variants will be set to `Default::default()`.
|
||||
/// The macro implements `strum::IntoEnumIter` on your enum and creates a new type called `YourEnumIter` that is the iterator object.
|
||||
/// You cannot derive `EnumIter` on any type with a lifetime bound (`<'a>`) because the iterator would surely
|
||||
/// create [unbounded lifetimes](https://doc.rust-lang.org/nightly/nomicon/unbounded-lifetimes.html).
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// // You need to bring the trait into scope to use it!
|
||||
/// use strum::IntoEnumIterator;
|
||||
/// use strum_macros::EnumIter;
|
||||
///
|
||||
/// #[derive(EnumIter, Debug, PartialEq)]
|
||||
/// enum Color {
|
||||
/// Red,
|
||||
/// Green { range: usize },
|
||||
/// Blue(usize),
|
||||
/// Yellow,
|
||||
/// }
|
||||
///
|
||||
/// // It's simple to iterate over the variants of an enum.
|
||||
/// for color in Color::iter() {
|
||||
/// println!("My favorite color is {:?}", color);
|
||||
/// }
|
||||
///
|
||||
/// let mut ci = Color::iter();
|
||||
/// assert_eq!(Some(Color::Red), ci.next());
|
||||
/// assert_eq!(Some(Color::Green {range: 0}), ci.next());
|
||||
/// assert_eq!(Some(Color::Blue(0)), ci.next());
|
||||
/// assert_eq!(Some(Color::Yellow), ci.next());
|
||||
/// assert_eq!(None, ci.next());
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "verbose-enumiter-name",
|
||||
proc_macro_derive(StrumEnumIter, attributes(strum))
|
||||
@ -164,6 +414,70 @@ pub fn enum_iter(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Add a verbose message to an enum variant.
|
||||
///
|
||||
/// Encode strings into the enum itself. The `strum_macros::EmumMessage` macro implements the `strum::EnumMessage` trait.
|
||||
/// `EnumMessage` looks for `#[strum(message="...")]` attributes on your variants.
|
||||
/// You can also provided a `detailed_message="..."` attribute to create a seperate more detailed message than the first.
|
||||
/// ```
|
||||
/// // You need to bring the trait into scope to use it
|
||||
/// use strum::EnumMessage;
|
||||
/// use strum_macros;
|
||||
///
|
||||
/// #[derive(strum_macros::EnumMessage, Debug)]
|
||||
/// #[allow(dead_code)]
|
||||
/// enum Color {
|
||||
/// #[strum(message = "Red", detailed_message = "This is very red")]
|
||||
/// Red,
|
||||
/// #[strum(message = "Simply Green")]
|
||||
/// Green { range: usize },
|
||||
/// #[strum(serialize = "b", serialize = "blue")]
|
||||
/// Blue(usize),
|
||||
/// }
|
||||
///
|
||||
/// // Generated code looks like more or less like this:
|
||||
/// /*
|
||||
/// impl ::strum::EnumMessage for Color {
|
||||
/// fn get_message(&self) -> ::std::option::Option<&str> {
|
||||
/// match self {
|
||||
/// &Color::Red => ::std::option::Option::Some("Red"),
|
||||
/// &Color::Green {..} => ::std::option::Option::Some("Simply Green"),
|
||||
/// _ => None
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn get_detailed_message(&self) -> ::std::option::Option<&str> {
|
||||
/// match self {
|
||||
/// &Color::Red => ::std::option::Option::Some("This is very red"),
|
||||
/// &Color::Green {..}=> ::std::option::Option::Some("Simply Green"),
|
||||
/// _ => None
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn get_serializations(&self) -> &[&str] {
|
||||
/// match self {
|
||||
/// &Color::Red => {
|
||||
/// static ARR: [&'static str; 1] = ["Red"];
|
||||
/// &ARR
|
||||
/// },
|
||||
/// &Color::Green {..}=> {
|
||||
/// static ARR: [&'static str; 1] = ["Green"];
|
||||
/// &ARR
|
||||
/// },
|
||||
/// &Color::Blue (..) => {
|
||||
/// static ARR: [&'static str; 2] = ["b", "blue"];
|
||||
/// &ARR
|
||||
/// },
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// */
|
||||
///
|
||||
/// let c = Color::Red;
|
||||
/// assert_eq!("Red", c.get_message().unwrap());
|
||||
/// assert_eq!("This is very red", c.get_detailed_message().unwrap());
|
||||
/// assert_eq!(["Red"], c.get_serializations());
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "verbose-enummessage-name",
|
||||
proc_macro_derive(StrumEnumMessage, attributes(strum))
|
||||
@ -180,6 +494,48 @@ pub fn enum_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Add custom properties to enum variants.
|
||||
///
|
||||
/// Enables the encoding of arbitary constants into enum variants. This method
|
||||
/// currently only supports adding additional string values. Other types of literals are still
|
||||
/// experimental in the rustc compiler. The generated code works by nesting match statements.
|
||||
/// The first match statement matches on the type of the enum, and the inner match statement
|
||||
/// matches on the name of the property requested. This design works well for enums with a small
|
||||
/// number of variants and properties, but scales linearly with the number of variants so may not
|
||||
/// be the best choice in all situations.
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// use strum_macros;
|
||||
/// // bring the trait into scope
|
||||
/// use strum::EnumProperty;
|
||||
///
|
||||
/// #[derive(strum_macros::EnumProperty, Debug)]
|
||||
/// #[allow(dead_code)]
|
||||
/// enum Color {
|
||||
/// #[strum(props(Red = "255", Blue = "255", Green = "255"))]
|
||||
/// White,
|
||||
/// #[strum(props(Red = "0", Blue = "0", Green = "0"))]
|
||||
/// Black,
|
||||
/// #[strum(props(Red = "0", Blue = "255", Green = "0"))]
|
||||
/// Blue,
|
||||
/// #[strum(props(Red = "255", Blue = "0", Green = "0"))]
|
||||
/// Red,
|
||||
/// #[strum(props(Red = "0", Blue = "0", Green = "255"))]
|
||||
/// Green,
|
||||
/// }
|
||||
///
|
||||
/// let my_color = Color::Red;
|
||||
/// let display = format!(
|
||||
/// "My color is {:?}. It's RGB is {},{},{}",
|
||||
/// my_color,
|
||||
/// my_color.get_str("Red").unwrap(),
|
||||
/// my_color.get_str("Green").unwrap(),
|
||||
/// my_color.get_str("Blue").unwrap()
|
||||
/// );
|
||||
/// assert_eq!("My color is Red. It\'s RGB is 255,0,0", &display);
|
||||
/// ```
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "verbose-enumproperty-name",
|
||||
proc_macro_derive(StrumEnumProperty, attributes(strum))
|
||||
@ -196,6 +552,53 @@ pub fn enum_properties(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Generate a new type with only the discriminant names.
|
||||
///
|
||||
/// Given an enum named `MyEnum`, generates another enum called `MyEnumDiscriminants` with the same variants, without any data fields.
|
||||
/// This is useful when you wish to determine the variant of an enum from a String, but the variants contain any
|
||||
/// non-`Default` fields. By default, the generated enum has the following derives:
|
||||
/// `Clone, Copy, Debug, PartialEq, Eq`. You can add additional derives using the
|
||||
/// `#[strum_discriminants(derive(AdditionalDerive))]` attribute.
|
||||
///
|
||||
/// ```
|
||||
/// // Bring trait into scope
|
||||
/// use std::str::FromStr;
|
||||
/// use strum::IntoEnumIterator;
|
||||
/// use strum_macros::{EnumDiscriminants, EnumIter, EnumString};
|
||||
///
|
||||
/// #[derive(Debug)]
|
||||
/// struct NonDefault;
|
||||
///
|
||||
/// // simple example
|
||||
/// # #[allow(dead_code)]
|
||||
/// #[derive(Debug, EnumDiscriminants)]
|
||||
/// #[strum_discriminants(derive(EnumString))]
|
||||
/// enum MyEnum {
|
||||
/// Variant0(NonDefault),
|
||||
/// Variant1 { a: NonDefault },
|
||||
/// }
|
||||
///
|
||||
/// // You can also rename the generated enum using the `#[strum_discriminants(name(OtherName))]` attribute:
|
||||
/// # #[allow(dead_code)]
|
||||
/// #[derive(Debug, EnumDiscriminants)]
|
||||
/// #[strum_discriminants(derive(EnumIter))]
|
||||
/// #[strum_discriminants(name(MyVariants))]
|
||||
/// enum MyEnumR {
|
||||
/// Variant0(bool),
|
||||
/// Variant1 { a: bool },
|
||||
/// }
|
||||
///
|
||||
/// // test simple example
|
||||
/// assert_eq!(
|
||||
/// MyEnumDiscriminants::Variant0,
|
||||
/// MyEnumDiscriminants::from_str("Variant0").unwrap()
|
||||
/// );
|
||||
/// // test rename example combined with EnumIter
|
||||
/// assert_eq!(
|
||||
/// vec![MyVariants::Variant0, MyVariants::Variant1],
|
||||
/// MyVariants::iter().collect::<Vec<_>>()
|
||||
/// );
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "verbose-enumdiscriminants-name",
|
||||
proc_macro_derive(StrumEnumDiscriminants, attributes(strum, strum_discriminants))
|
||||
@ -212,6 +615,30 @@ pub fn enum_discriminants(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
||||
toks.into()
|
||||
}
|
||||
|
||||
/// Add a constant `usize` equal to the number of variants.
|
||||
///
|
||||
/// For a given enum generates implementation of `strum::EnumCount`,
|
||||
/// which adds a static property `COUNT` of type usize that holds the number of variants.
|
||||
///
|
||||
/// ```
|
||||
/// use strum::{EnumCount, IntoEnumIterator};
|
||||
/// use strum_macros::{EnumCount as EnumCountMacro, EnumIter};
|
||||
///
|
||||
/// #[derive(Debug, EnumCountMacro, EnumIter)]
|
||||
/// enum Week {
|
||||
/// Sunday,
|
||||
/// Monday,
|
||||
/// Tuesday,
|
||||
/// Wednesday,
|
||||
/// Thursday,
|
||||
/// Friday,
|
||||
/// Saturday,
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(7, Week::COUNT);
|
||||
/// assert_eq!(Week::iter().count(), Week::COUNT);
|
||||
///
|
||||
/// ```
|
||||
#[cfg_attr(
|
||||
feature = "verbose-enumcount-name",
|
||||
proc_macro_derive(StrumEnumCount, attributes(strum))
|
||||
|
Loading…
Reference in New Issue
Block a user