### Derive EnumString for Enum Parsing Source: https://github.com/peternator7/strum/wiki/Derive-EnumString This example demonstrates deriving `EnumString` for an enum with various variant types, including simple variants, tuple variants with data, and variants with custom serialization names. It also shows how to disable a variant. ```rust use strum; use strum_macros::EnumString; use std::str::FromStr; #[derive(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="true")] 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 { 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), } } } */ pub fn main() { let color_variant = Color::from_str("Red").unwrap(); assert!(Color:Red, color_variant); } ``` -------------------------------- ### Get Static Slice of Variant Names with VariantNames Source: https://context7.com/peternator7/strum/llms.txt Implement `strum::VariantNames` to add a `VARIANTS: &'static [&'static str]` associated constant. This respects `serialize_all` case transformations and is useful for populating UI elements. ```rust use strum::VariantNames; use strum_macros::VariantNames; #[derive(Debug, VariantNames)] #[strum(serialize_all = "SCREAMING_SNAKE_CASE")] enum LogLevel { Trace, Debug, Info, Warn, Error, } fn main() { assert_eq!( &["TRACE", "DEBUG", "INFO", "WARN", "ERROR"], LogLevel::VARIANTS ); // Useful for populating a CLI or UI select list for name in LogLevel::VARIANTS { println!("Supported level: {}", name); } } ``` -------------------------------- ### Derive EnumCount and EnumIter for an Enum Source: https://github.com/peternator7/strum/wiki/Derive-EnumCount Use the `#[derive(EnumCount, EnumIter)]` attribute to automatically implement `EnumCount` and `EnumIter` for your enum. This allows you to get the number of variants via `EnumCount::count()` and iterate over variants using `EnumIter::iter()`. The example also shows the generated `WEEK_COUNT` constant. ```rust extern crate strum; #[macro_use] extern crate strum_macros; use strum::{IntoEnumIterator, EnumCount}; #[derive(Debug, EnumCount, EnumIter)] enum Week { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, } fn main() { assert_eq!(7, Week::count()); assert_eq!(Week::count(), WEEK_COUNT); assert_eq!(Week::iter().count(), WEEK_COUNT); } ``` -------------------------------- ### Deriving IntoStaticStr for an Enum Source: https://github.com/peternator7/strum/wiki/Derive-IntoStaticStr Use the `#[derive(IntoStaticStr)]` attribute on your enum to enable conversion to `&'static str`. This example shows an enum with a variant containing a string slice, demonstrating how lifetimes are handled. ```rust extern crate strum; #[macro_use] extern crate strum_macros; #[derive(IntoStaticStr)] enum State<'a> { Initial(&'a str), Finished } fn print_state<'a>(s:&'a str) { let state = State::Initial(s); // The following won't work because the lifetime is incorrect so we can use.as_static() instead. // let wrong: &'static str = state.as_ref(); let right: &'static str = state.into(); println!("{}", right); } fn main() { print_state(&"hello world".to_string()) } ``` -------------------------------- ### Get Enum Variant Count at Compile Time with EnumCount Source: https://context7.com/peternator7/strum/llms.txt Implement `strum::EnumCount` to add a `COUNT: usize` associated constant. Disabled variants (marked `#[strum(disabled)]`) are excluded from the count. This count is consistent with `iter().count()`. ```rust use strum::{EnumCount, IntoEnumIterator}; use strum_macros::{EnumCount as EnumCountMacro, EnumIter}; #[derive(Debug, EnumCountMacro, EnumIter)] enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, } fn main() { assert_eq!(7, Day::COUNT); // COUNT and iter().count() are always consistent assert_eq!(Day::COUNT, Day::iter().count()); println!("There are {} days in a week.", Day::COUNT); } ``` -------------------------------- ### Get Static Slice of Variant Values with VariantArray Source: https://context7.com/peternator7/strum/llms.txt Implement `strum::VariantArray` to add a `VARIANTS: &'static [Self]` associated constant containing the enum variant values. This macro only works on enums with unit-type variants and provides direct value access. ```rust use strum::VariantArray; use strum_macros::VariantArray; #[derive(VariantArray, Debug, PartialEq, Clone, Copy)] enum Suit { Clubs, Diamonds, Hearts, Spades, } fn main() { assert_eq!(Suit::VARIANTS, &[Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades]); assert_eq!(4, Suit::VARIANTS.len()); // Direct value access without iteration overhead let first: Suit = Suit::VARIANTS[0]; assert_eq!(Suit::Clubs, first); } ``` -------------------------------- ### EnumVariantNames with clap Integration Source: https://github.com/peternator7/strum/wiki/Derive-EnumVariantNames Demonstrates how to use `EnumVariantNames` with clap for command-line argument parsing. Ensure `clap` and `strum` are added as dependencies. The `VARIANTS` static array is directly usable with clap's `possible_values`. ```rust use strum::{EnumString, EnumVariantNames}; use strum::VariantNames; #[derive(EnumString, EnumVariantNames)] #[strum(serialize_all = "kebab_case")] enum Color { Red, Blue, Yellow, RebeccaPurple, } fn main() { // This is what you get: assert_eq!( &Color::VARIANTS, &["red", "blue", "yellow", "rebecca-purple"] ); // Use it with clap like this: let args = clap::App::new("app") .arg(Arg::with_name("color") .long("color") .possible_values(&Color::VARIANTS) .case_insensitive(true)) .get_matches(); // ... } ``` -------------------------------- ### Add Strum to Cargo.toml Source: https://github.com/peternator7/strum/blob/master/README.md Include strum and strum_macros in your project's dependencies to utilize its features. The 'derive' feature allows importing macros directly from the 'strum' crate. ```toml [dependencies] strum = "0.28" strum_macros = "0.28" # You can also use the "derive" feature, and import the macros directly from "strum" # strum = { version = "0.28", features = ["derive"] } ``` -------------------------------- ### Derive EnumProperty for Color Enum Source: https://github.com/peternator7/strum/wiki/Derive-EnumProperty Demonstrates how to derive EnumProperty for an enum and assign string properties to its variants. Ensure the EnumProperty trait is in scope. ```rust # extern crate strum; # #[macro_use] extern crate strum_macros; # use std::fmt::Debug; // You need to bring the type into scope to use it!!! use strum::EnumProperty; #[derive(EnumProperty,Debug)] 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, } fn main() { 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()); } ``` -------------------------------- ### EnumVariantNames with structopt Integration Source: https://github.com/peternator7/strum/wiki/Derive-EnumVariantNames Shows how to integrate `EnumVariantNames` with structopt for defining command-line interfaces. The `variants()` method is used to provide possible values for an argument. Note that `structopt` is deprecated in favor of `clap` v3+. ```rust #[derive(Debug, StructOpt)] struct Cli { /// The main color #[structopt(long = "color", default_value = "Color::Blue", raw(possible_values = "&Color::variants()"))] color: Color, } ``` -------------------------------- ### Cargo.toml Configuration for Macro Renaming Source: https://github.com/peternator7/strum/wiki/Macro-Renames Configure `Cargo.toml` to enable specific Strum features for macro renaming. This is useful for older Rust versions to avoid macro name collisions. ```toml strum = { version = "0.14" } strum_macros = { version = "0.14", features = [ "verbose-tostring-name" ] } ``` -------------------------------- ### Deriving Display for an Enum Source: https://github.com/peternator7/strum/wiki/Derive-Display Demonstrates deriving `Display` for an enum with various variants and attributes. Use `#[strum(serialize = "...")]` to specify a custom string representation. The `to_string` method is automatically implemented. ```rust // You need to bring the type into scope to use it!!! use std::string::ToString; #[derive(Display, Debug)] enum Color { #[strum(serialize="redred")] Red, Green { range:usize }, Blue(usize), Yellow, } // It's simple to iterate over the variants of an enum. fn debug_colors() { let red = Color::Red; assert_eq!(String::from("redred"), red.to_string()); } fn main() { debug_colors(); } ``` -------------------------------- ### Rust Enum Serialization with snake_case Source: https://github.com/peternator7/strum/wiki/Additional-Attributes Demonstrates using `#[strum(serialize_all = "snake_case")]` to control the case for enum serialization and deserialization. This attribute is applied at the enum level. ```rust extern crate strum; #[macro_use] extern crate strum_macros; #[derive(Debug, Eq, PartialEq, ToString)] #[strum(serialize_all = "snake_case")] enum Brightness { DarkBlack, Dim { glow: usize, }, #[strum(serialize = "bright")] BrightWhite, } fn main() { 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() ); } ``` -------------------------------- ### Convert Enum Variants to Strings with Display Source: https://context7.com/peternator7/strum/llms.txt Derive `std::fmt::Display` for enums using the Display macro. Supports custom string representations, fallback to variant names, and type-level prefixes/suffixes. Variants with fields can use format string interpolation. ```rust use strum_macros::Display; #[derive(Display, Debug)] #[strum(serialize_all = "kebab-case")] enum HttpMethod { Get, Post, #[strum(to_string = "PUT")] Put, // Field interpolation #[strum(to_string = "PATCH (affects {field})")] Patch { field: String }, } #[derive(Display, Debug)] #[strum(prefix = "/api/", suffix = "/")] enum Route { Users, Products, } fn main() { assert_eq!("get", HttpMethod::Get.to_string()); assert_eq!("post", HttpMethod::Post.to_string()); assert_eq!("PUT", HttpMethod::Put.to_string()); assert_eq!( "PATCH (affects email)", HttpMethod::Patch { field: "email".to_string() }.to_string() ); assert_eq!("/api/Users/", Route::Users.to_string()); assert_eq!("/api/Products/", Route::Products.to_string()); } ``` -------------------------------- ### Inspect generated macro code with STRUM_DEBUG Source: https://context7.com/peternator7/strum/llms.txt Set the STRUM_DEBUG environment variable to '1' or a specific enum name to print the proc-macro-generated Rust code to stdout during compilation. This is helpful for understanding and debugging the output of strum's derive macros. ```bash # Dump generated code for ALL types in the crate STRUM_DEBUG=1 cargo build # Dump generated code only for the enum named "Direction" STRUM_DEBUG=Direction cargo build ``` -------------------------------- ### Iterate Over Enum Variants with EnumIter Source: https://context7.com/peternator7/strum/llms.txt Implement `strum::IntoEnumIterator` for enums using the EnumIter macro. This provides an iterator over all enum variants, supporting forward and reverse iteration, and exact sizing. Variants with fields are initialized using `Default::default()`. ```rust use strum::IntoEnumIterator; use strum_macros::EnumIter; #[derive(Debug, PartialEq, EnumIter)] enum Planet { Mercury, Venus, Earth, Mars, } fn main() { // Forward iteration let planets: Vec<_> = Planet::iter().collect(); assert_eq!(planets, vec![Planet::Mercury, Planet::Venus, Planet::Earth, Planet::Mars]); // Reverse iteration let mut rev = Planet::iter().rev(); assert_eq!(Some(Planet::Mars), rev.next()); assert_eq!(Some(Planet::Earth), rev.next()); // Exact size assert_eq!(4, Planet::iter().len()); // Generic over IntoEnumIterator fn print_all() { for variant in E::iter() { println!("{:?}", variant); } } print_all::(); } ``` -------------------------------- ### Bulk case conversion with #[strum(serialize_all)] Source: https://context7.com/peternator7/strum/llms.txt The `#[strum(serialize_all = "...")]` attribute applies a specified case style (e.g., kebab-case, camelCase) to all enum variant names during serialization and deserialization. Per-variant overrides using `#[strum(serialize = "...")]` are still supported. ```rust use std::str::FromStr; use strum_macros::{Display, EnumString}; #[derive(Display, EnumString, Debug, PartialEq)] #[strum(serialize_all = "kebab-case")] enum CssProperty { FontSize, BackgroundColor, BorderRadius, #[strum(serialize = "z-index")] // per-variant override still works ZIndex, } fn main() { // Display uses kebab-case assert_eq!("font-size", CssProperty::FontSize.to_string()); assert_eq!("background-color", CssProperty::BackgroundColor.to_string()); assert_eq!("border-radius", CssProperty::BorderRadius.to_string()); assert_eq!("z-index", CssProperty::ZIndex.to_string()); // FromStr parses kebab-case assert_eq!(CssProperty::FontSize, CssProperty::from_str("font-size").unwrap()); assert_eq!(CssProperty::ZIndex, CssProperty::from_str("z-index").unwrap()); } ``` -------------------------------- ### Convert Enum Variants to &'static str with IntoStaticStr Source: https://context7.com/peternator7/strum/llms.txt Implement `From for &'static str` using `IntoStaticStr`. This is useful when a `'static` lifetime is required and `AsRef` is insufficient. ```rust use strum_macros::IntoStaticStr; #[derive(IntoStaticStr, Debug)] enum Status<'a> { Active, Pending, Label(&'a str), // lifetime on variant data — static str still returned for variant name } fn log_status(s: &'static str) { println!("Status: {}", s); } fn main() { let s = Status::Active; let label: &'static str = s.into(); assert_eq!("Active", label); log_status(label); // &'static str required here let pending = Status::Pending; let p: &'static str = (&pending).into(); assert_eq!("Pending", p); } ``` -------------------------------- ### Generate try_as_variant() methods with EnumTryAs Source: https://context7.com/peternator7/strum/llms.txt EnumTryAs derives `try_as_{variant_name}()` methods for tuple-style enum variants. These methods attempt to extract the variant's inner data, returning an Option containing the fields if the variant matches, or None otherwise. Named and unit variants are ignored. ```rust use strum_macros::EnumTryAs; #[derive(EnumTryAs, Debug)] enum Message { Quit, Move { x: i32, y: i32 }, // named — skipped Write(String), // tuple — gets try_as_write() Color(u8, u8, u8), // tuple — gets try_as_color() } fn main() { let msg = Message::Write("hello".to_string()); assert_eq!(Some("hello".to_string()), msg.try_as_write()); let rgb = Message::Color(255, 128, 0); assert_eq!(Some((255_u8, 128_u8, 0_u8)), rgb.try_as_color()); // Returns None when variant doesn't match assert_eq!(None, Message::Quit.try_as_write()); // Practical use: process only Write messages let messages = vec![ Message::Quit, Message::Write("first".into()), Message::Color(0, 0, 0), Message::Write("second".into()), ]; let texts: Vec = messages.into_iter() .filter_map(|m| m.try_as_write()) .collect(); assert_eq!(vec!["first", "second"], texts); } ``` -------------------------------- ### Tokenize Inputs with EnumString Source: https://github.com/peternator7/strum/wiki/Examples Utilize EnumString to convert string inputs into enum variants, including a default variant for unrecognized tokens. ```rust extern crate strum; #[macro_use] extern crate strum_macros; use std::str::FromStr; #[derive(Eq, PartialEq, Debug, EnumString)] enum Tokens { #[strum(serialize="fn")] Function, #[strum(serialize="(")] OpenParen, #[strum(serialize=")")] CloseParen, #[strum(default="true")] Ident(String) } fn main() { let toks = ["fn", "hello_world", "(", ")"].iter() .map(|tok| Tokens::from_str(tok).unwrap()) .collect::>(); assert_eq!(toks, vec![Tokens::Function, Tokens::Ident(String::from("hello_world")), Tokens::OpenParen, Tokens::CloseParen]); } ``` -------------------------------- ### Rust Enum Variant Serialization Override Source: https://github.com/peternator7/strum/wiki/Additional-Attributes Shows how to use `#[strum(serialize = "...")]` on individual enum variants to override the default serialization behavior. This allows specific variants to have custom string representations. ```rust #[strum(serialize = "bright")] BrightWhite ``` -------------------------------- ### Implement AsRef for Enum Variants with AsRefStr Source: https://context7.com/peternator7/strum/llms.txt Use `AsRefStr` to implement `AsRef` for enum variants, returning borrowed string slices. Supports `serialize` and `to_string` attributes, as well as type-level `prefix` and `suffix`. ```rust use strum_macros::AsRefStr; #[derive(AsRefStr, Debug)] #[strum(prefix = "role:")] enum UserRole { #[strum(serialize = "admin")] Admin, Moderator, Guest, } fn requires_role(role: &str) -> bool { role == "role:admin" } fn main() { assert_eq!("role:admin", UserRole::Admin.as_ref()); assert_eq!("role:Moderator", UserRole::Moderator.as_ref()); assert_eq!("role:Guest", UserRole::Guest.as_ref()); assert!(requires_role(UserRole::Admin.as_ref())); // Zero allocation string formatting println!("Current role: {}", UserRole::Guest.as_ref()); } ``` -------------------------------- ### Attach Properties to Enum Variants with EnumProperty Source: https://context7.com/peternator7/strum/llms.txt The EnumProperty derive macro allows attaching arbitrary key-value properties to enum variants. Use get_str, get_int, and get_bool to retrieve these properties. ```rust use strum::EnumProperty; use strum_macros::EnumProperty; #[derive(EnumProperty, Debug)] enum Permission { #[strum(props(level = "0", label = "Read Only", audited = true))] ReadOnly, #[strum(props(level = "1", label = "Read Write", audited = true))] ReadWrite, #[strum(props(level = "2", label = "Admin", audited = true, dangerous = true))] Admin, } fn main() { let perm = Permission::Admin; assert_eq!(Some("Admin"), perm.get_str("label")); assert_eq!(Some(2_i64), perm.get_int("level")); assert_eq!(Some(true), perm.get_bool("audited")); assert_eq!(Some(true), perm.get_bool("dangerous")); assert_eq!(None, Permission::ReadOnly.get_bool("dangerous")); // Practical use: authorization check fn requires_audit(p: &Permission) -> bool { p.get_bool("audited").unwrap_or(false) } assert!(requires_audit(&Permission::Admin)); assert!(requires_audit(&Permission::ReadOnly)); } ``` -------------------------------- ### Convert Original Enum to Discriminants Enum Source: https://github.com/peternator7/strum/wiki/Derive-EnumDiscriminants Demonstrates the automatic `From` trait implementations that allow converting the original enum variant into its corresponding discriminant enum variant. This is useful for obtaining the discriminant from an instance of the original enum. ```rust extern crate strum; #[macro_use] extern crate strum_macros; #[derive(Debug, EnumDiscriminants)] #[strum_discriminants(name(MyVariants))] enum MyEnum { Variant0(bool), Variant1 { a: bool }, } fn main() { assert_eq!(MyVariants::Variant0, MyEnum::Variant0(true).into()); } ``` -------------------------------- ### Attach Messages to Enum Variants with EnumMessage Source: https://context7.com/peternator7/strum/llms.txt Use the EnumMessage derive macro to attach static string messages and detailed messages to enum variants. This avoids runtime allocations when retrieving messages. ```rust use strum::EnumMessage; use strum_macros::EnumMessage; #[derive(EnumMessage, Debug)] enum AppError { /// Low-level I/O failure. #[strum(message = "I/O Error", detailed_message = "An I/O error occurred. Check file permissions.")] IoError, #[strum(message = "Network Error", detailed_message = "Could not reach the remote server.")] NetworkError, #[strum(serialize = "auth", serialize = "authentication_error", message = "Authentication Failed")] AuthError, } fn main() { let err = AppError::IoError; assert_eq!(Some("I/O Error"), err.get_message()); assert_eq!(Some("An I/O error occurred. Check file permissions."), err.get_detailed_message()); assert_eq!(Some("Low-level I/O failure."), err.get_documentation()); let auth = AppError::AuthError; assert_eq!(Some("Authentication Failed"), auth.get_message()); // get_serializations returns all serialize aliases assert_eq!(&["auth", "authentication_error"], auth.get_serializations()); } ``` -------------------------------- ### Derive EnumMessage with Custom Messages Source: https://github.com/peternator7/strum/wiki/Derive-EnumMessage Use the `EnumMessage` derive macro to add string messages to enum variants using `strum(message="...")` attributes. You can also provide a `detailed_message="..."` attribute for a more detailed message. Ensure the type is in scope to use it. ```rust use strum::EnumMessage; #[derive(EnumMessage,Debug)] 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 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 }, } } } */ ``` -------------------------------- ### Parse Strings to Enum Variants with EnumString Source: https://context7.com/peternator7/strum/llms.txt Use EnumString to derive `std::str::FromStr` for enums, enabling string-to-variant conversion. Supports custom serialization names, aliases, case-insensitive matching, and a default catch-all variant for infallible parsing. ```rust use std::str::FromStr; use strum_macros::EnumString; #[derive(Debug, PartialEq, EnumString)] #[strum(serialize_all = "snake_case")] enum Direction { North, South, // Multiple aliases accepted #[strum(serialize = "e", serialize = "east")] East, // Excluded from parsing #[strum(disabled)] Unknown, // Case-insensitive ASCII matching #[strum(ascii_case_insensitive)] West, // Default catch-all variant captures unmatched input #[strum(default)] Other(String), } fn main() { assert_eq!(Direction::North, Direction::from_str("north").unwrap()); assert_eq!(Direction::East, Direction::from_str("e").unwrap()); assert_eq!(Direction::East, Direction::from_str("east").unwrap()); assert_eq!(Direction::West, Direction::from_str("WEST").unwrap()); // case-insensitive assert!(Direction::from_str("Unknown").is_err()); // disabled // With default variant, infallible From<&str> is also available: let d: Direction = Direction::from("totally_unknown"); assert_eq!(Direction::Other("totally_unknown".to_string()), d); } ``` -------------------------------- ### Rust Enum Default Variant Handling Source: https://github.com/peternator7/strum/wiki/Additional-Attributes Illustrates the `#[strum(default)]` attribute for handling parsing errors. When applied to a variant, it captures the input string if no other variant matches, preventing a `ParseError::VariantNotFound`. ```rust // Replaces this: _ => Err(strum::ParseError::VariantNotFound) // With this in generated code: default => Ok(Variant(default.into())) ``` -------------------------------- ### Generate is_variant() methods with EnumIs Source: https://context7.com/peternator7/strum/llms.txt Use EnumIs to automatically derive boolean predicate methods for each enum variant. These methods check if an enum instance matches a specific variant, useful for conditional logic and filtering. ```rust use strum_macros::EnumIs; #[derive(EnumIs, Debug)] enum ConnectionState { Connecting, Connected { peer: String }, Disconnected, Failed(String), } fn main() { let state = ConnectionState::Connected { peer: "192.168.1.1".into() }; assert!(state.is_connected()); assert!(!state.is_connecting()); assert!(!state.is_disconnected()); let err = ConnectionState::Failed("timeout".into()); assert!(err.is_failed()); assert!(!err.is_connected()); // Useful in filter chains let states = vec![ ConnectionState::Connecting, ConnectionState::Connected { peer: "10.0.0.1".into() }, ConnectionState::Disconnected, ]; let active: Vec<_> = states.iter().filter(|s| s.is_connected()).collect(); assert_eq!(1, active.len()); } ``` -------------------------------- ### Convert Integer Discriminants to Enum Variants with FromRepr Source: https://context7.com/peternator7/strum/llms.txt Add a `from_repr(discriminant) -> Option` associated function to enums using `FromRepr`. This respects explicit discriminant values and `#[repr(T)]` attributes. `from_repr` is `const` for enums without data fields. ```rust use strum_macros::FromRepr; #[derive(FromRepr, Debug, PartialEq)] #[repr(u8)] enum ErrorCode { Ok = 0, NotFound = 4, ServerError = 5, } // Unit-only enum: from_repr is const const fn decode(code: u8) -> Option { ErrorCode::from_repr(code) } fn main() { assert_eq!(Some(ErrorCode::Ok), ErrorCode::from_repr(0)); assert_eq!(Some(ErrorCode::NotFound), ErrorCode::from_repr(4)); assert_eq!(Some(ErrorCode::ServerError), ErrorCode::from_repr(5)); assert_eq!(None, ErrorCode::from_repr(99)); // Usable in const context const RESULT: Option = decode(4); assert_eq!(Some(ErrorCode::NotFound), RESULT); } ``` -------------------------------- ### Implement Error Trait with EnumMessage Source: https://github.com/peternator7/strum/wiki/Examples Use EnumMessage to quickly implement the Error trait for enums, providing custom messages and detailed messages. ```rust extern crate strum; #[macro_use] extern crate strum_macros; use std::error::Error; use std::fmt::*; use strum::EnumMessage; #[derive(Debug, EnumMessage)] enum ServerError { #[strum(message="A network error occured")] #[strum(detailed_message="Try checking your connection.")] NetworkError, #[strum(message="User input error.")] #[strum(detailed_message="There was an error parsing user input. Please try again.")] InvalidUserInputError, } impl Display for ServerError { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "{}", self.get_message().unwrap()) } } impl Error for ServerError { fn description(&self) -> &str { self.get_detailed_message().unwrap() } } ``` -------------------------------- ### Generate Discriminant Mirror Enum with EnumDiscriminants Source: https://context7.com/peternator7/strum/llms.txt The EnumDiscriminants macro generates a companion enum with the same variant names but no data fields. It implements From and can derive other traits like EnumString, EnumIter, and EnumMessage. ```rust use std::str::FromStr; use strum::{IntoEnumIterator, EnumMessage as _}; use strum_macros::{EnumDiscriminants, EnumIter, EnumString, EnumMessage}; #[derive(Debug)] struct Config { value: String } #[derive(Debug, EnumDiscriminants)] #[strum_discriminants(derive(EnumString, EnumIter, EnumMessage))] #[strum_discriminants(name(EventKind))] enum Event { #[strum_discriminants(strum(message = "User logged in"))] Login { user_id: u64, config: Config }, #[strum_discriminants(strum(message = "User logged out"))] Logout { user_id: u64 }, Tick, } fn main() { let event = Event::Login { user_id: 42, config: Config { value: "dark".into() } }; // Convert to discriminant without needing to match on data let kind: EventKind = (&event).into(); assert_eq!(EventKind::Login, kind); // Parse discriminant from string let parsed = EventKind::from_str("Logout").unwrap(); assert_eq!(EventKind::Logout, parsed); // Iterate over all possible event kinds let all_kinds: Vec<_> = EventKind::iter().collect(); assert_eq!(3, all_kinds.len()); // Access message on discriminant assert_eq!(Some("User logged in"), EventKind::Login.get_message()); } ``` -------------------------------- ### Derive EnumDiscriminants with EnumString Source: https://github.com/peternator7/strum/wiki/Derive-EnumDiscriminants Generates a discriminant enum that can be converted from a string using `EnumString`. Ensure the generated enum type is brought into scope to use it. ```rust extern crate strum; #[macro_use] extern crate strum_macros; // Bring trait into scope use std::str::FromStr; #[derive(Debug)] struct NonDefault; #[allow(dead_code)] #[derive(Debug, EnumDiscriminants)] #[strum_discriminants(derive(EnumString))] enum MyEnum { Variant0(NonDefault), Variant1 { a: NonDefault }, } fn main() { assert_eq!( MyEnumDiscriminants::Variant0, MyEnumDiscriminants::from_str("Variant0").unwrap() ); } ``` -------------------------------- ### Deriving EnumIter for an Enum Source: https://github.com/peternator7/strum/wiki/Derive-EnumIter Derive EnumIter on an enum to enable iteration over its variants. Associated data on variants will be set to `Default::default()`. This macro cannot be used on types with lifetime bounds. ```rust // You need to bring the type into scope to use it!!! use strum::IntoEnumIterator; #[derive(EnumIter,Debug)] enum Color { Red, Green { range:usize }, Blue(usize), Yellow, } // It's simple to iterate over the variants of an enum. fn debug_colors() { for color in Color::iter() { println!("My favorite color is {:?}", color); } } fn main() { debug_colors(); } ``` -------------------------------- ### Rename Generated Enum and Add EnumIter Derive Source: https://github.com/peternator7/strum/wiki/Derive-EnumDiscriminants Allows renaming the generated discriminant enum using `#[strum_discriminants(name(OtherName))]` and adding the `EnumIter` derive for iteration. You must bring the renamed type into scope to use it. ```rust extern crate strum; #[macro_use] extern crate strum_macros; // You need to bring the type into scope to use it!!! use strum::IntoEnumIterator; #[allow(dead_code)] #[derive(Debug, EnumDiscriminants)] #[strum_discriminants(derive(EnumIter))] #[strum_discriminants(name(MyVariants))] enum MyEnum { Variant0(bool), Variant1 { a: bool }, } fn main() { assert_eq!( vec![MyVariants::Variant0, MyVariants::Variant1], MyVariants::iter().collect::>() ); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.