### Use Custom Variant Names with Enum Dispatch (Rust) Source: https://context7.com/antonok/enum_dispatch/llms.txt This example demonstrates how to assign custom names to enum variants when using enum_dispatch. This is useful for disambiguation or when working with generics, allowing for more descriptive variant names in the generated enum. ```rust use enum_dispatch::enum_dispatch; struct TypeA { value: i32 } struct TypeB { data: String } impl MyTrait for TypeA { fn process(&self) -> String { format!("TypeA: {}", self.value) } } impl MyTrait for TypeB { fn process(&self) -> String { format!("TypeB: {}", self.data) } } #[enum_dispatch] trait MyTrait { fn process(&self) -> String; } #[enum_dispatch(MyTrait)] enum MyTypes { TypeA, CustomVariantName(TypeB), // Custom name for TypeB variant } fn main() { let a: MyTypes = TypeA { value: 42 }.into(); let b: MyTypes = TypeB { data: "hello".to_string() }.into(); // Pattern matching uses custom variant name match b { MyTypes::TypeA(inner) => println!("TypeA: {:?}", inner.value), MyTypes::CustomVariantName(inner) => println!("TypeB: {}", inner.data), } assert_eq!(a.process(), "TypeA: 42"); assert_eq!(b.process(), "TypeB: hello"); } ``` -------------------------------- ### Troubleshooting Enum Parsing with Imports in enum_dispatch Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md This example illustrates a common issue where enum variants are not in scope, causing compilation errors. The solution involves importing the necessary types before defining the enum. ```rust use crate::A::TypeA; use crate::B::TypeB; #[enum_dispatch] enum Succeeds { TypeA, TypeB, } ``` -------------------------------- ### Custom Variant Names with Enum Dispatch in Rust Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md Illustrates how to define custom variant names within an enum managed by `enum_dispatch`. This is useful for distinguishing between different types or when dealing with enums and traits that have generic type arguments. The example shows how to use a custom name `CustomVariantName` for `TypeB` and how to match on these variants. ```rust #[enum_dispatch] enum MyTypes { TypeA, CustomVariantName(TypeB), } let mt: MyTypes = TypeB::new().into(); match mt { TypeA(a) => { /* `a` is a TypeA */ }, CustomVariantName(b) => { /* `b` is a TypeB */ }, } ``` -------------------------------- ### Dynamic vs. Enum Dispatch in Rust Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md Demonstrates the performance difference between traditional dynamic dispatch using trait objects and optimized dispatch using `enum_dispatch`. The first snippet shows standard dynamic dispatch with `Box`, while the second illustrates the `enum_dispatch` approach using a generated enum for faster method calls without dynamic dispatch. ```rust trait MyBehavior { fn my_trait_method(&self); } // We already have defined MyImplementorA and MyImplementorB, and implemented MyBehavior for each. // Any pointer type -- Box, &, etc. let a: Box = Box::new(MyImplementorA::new()); a.my_trait_method(); //dynamic dispatch ``` ```rust #[enum_dispatch] enum MyBehaviorEnum { MyImplementorA, MyImplementorB, } #[enum_dispatch(MyBehaviorEnum)] trait MyBehavior { fn my_trait_method(&self); } let a: MyBehaviorEnum = MyImplementorA::new().into(); a.my_trait_method(); //no dynamic dispatch ``` -------------------------------- ### Conditional Enum Dispatch in Rust using cfg Attributes Source: https://context7.com/antonok/enum_dispatch/llms.txt This Rust code uses the `enum_dispatch` crate to conditionally compile enum variants based on target operating system configurations. It defines a `SystemHandler` trait and an enum `Handler` with platform-specific implementations for Windows, Linux, and macOS, falling back to a general handler if none of the specific targets match. The `main` function instantiates the appropriate handler and calls its `handle` method. ```rust use enum_dispatch::enum_dispatch; struct WindowsHandler; struct UnixHandler; struct MacHandler; struct FallbackHandler; impl SystemHandler for WindowsHandler { fn handle(&self) -> String { "Windows".to_string() } } impl SystemHandler for UnixHandler { fn handle(&self) -> String { "Unix".to_string() } } impl SystemHandler for MacHandler { fn handle(&self) -> String { "Mac".to_string() } } impl SystemHandler for FallbackHandler { fn handle(&self) -> String { "Fallback".to_string() } } #[enum_dispatch] trait SystemHandler { fn handle(&self) -> String; } #[enum_dispatch(SystemHandler)] enum Handler { #[cfg(target_os = "windows")] WindowsHandler, #[cfg(target_os = "linux")] UnixHandler, #[cfg(target_os = "macos")] MacHandler, #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))] FallbackHandler, } fn main() { #[cfg(target_os = "windows")] let handler: Handler = WindowsHandler.into(); #[cfg(target_os = "linux")] let handler: Handler = UnixHandler.into(); #[cfg(target_os = "macos")] let handler: Handler = MacHandler.into(); #[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos")))] let handler: Handler = FallbackHandler.into(); println!("System: {}", handler.handle()); } ``` -------------------------------- ### 'From' Implementation Generation by enum_dispatch Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md Demonstrates the `From` trait implementations generated by `enum_dispatch`. These allow for easy creation of enum variants from their corresponding inner types, simplifying initialization. ```rust impl From for MyBehaviorEnum { fn from(inner: MyImplementorA) -> MyBehaviorEnum { MyBehaviorEnum::MyImplementorA(inner) } } impl From for MyBehaviorEnum { fn from(inner: MyImplementorB) -> MyBehaviorEnum { MyBehaviorEnum::MyImplementorB(inner) } } ``` -------------------------------- ### Performance Comparison: enum_dispatch vs. Dynamic Dispatch in Rust Source: https://context7.com/antonok/enum_dispatch/llms.txt A benchmark comparing the performance of enum_dispatch against traditional dynamic dispatch (Box) when accessing trait objects within collections. The results highlight the significant performance advantage of enum_dispatch. ```rust use enum_dispatch::enum_dispatch; struct Zero; struct One; impl ReturnsValue for Zero { fn return_value(&self) -> usize { 0 } } impl ReturnsValue for One { fn return_value(&self) -> usize { 1 } } #[enum_dispatch] trait ReturnsValue { fn return_value(&self) -> usize; } #[enum_dispatch(ReturnsValue)] enum EnumDispatched { Zero, One, } fn benchmark_enum_dispatch() { const ITERATIONS: usize = 1000000; let dis0 = EnumDispatched::from(Zero); let dis1 = EnumDispatched::from(One); for _ in 0..ITERATIONS { let _ = dis0.return_value(); let _ = dis1.return_value(); } } fn benchmark_box_dyn() { const ITERATIONS: usize = 1000000; let dis0: Box = Box::new(Zero); let dis1: Box = Box::new(One); for _ in 0..ITERATIONS { let _ = dis0.return_value(); let _ = dis1.return_value(); } } fn main() { // enum_dispatch version runs ~10x faster // Benchmark results show: // - boxdyn: ~2,131,736 ns/iter // - enum_dispatch: ~471,740 ns/iter benchmark_enum_dispatch(); benchmark_box_dyn(); } ``` -------------------------------- ### Trait Implementation Generation by enum_dispatch Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md Shows a sample of the `impl` block generated by `enum_dispatch` to implement a trait for an enum. This involves a `match` statement that dispatches calls to the appropriate inner type's method. ```rust impl MyBehavior for MyBehaviorEnum { fn my_trait_method(&self) { match self { MyBehaviorEnum::MyImplementorA(inner) => inner.my_trait_method(), MyBehaviorEnum::MyImplementorB(inner) => inner.my_trait_method(), } } } ``` -------------------------------- ### Basic enum_dispatch Attribute on Trait and Enum in Rust Source: https://context7.com/antonok/enum_dispatch/llms.txt Demonstrates the core usage of the `#[enum_dispatch]` attribute to link a trait (`KnobControl`) with an enum (`Knob`). This automatically generates trait implementations for the enum, delegating method calls to the appropriate variant, thus avoiding vtable overhead. It includes automatic `From` implementations for easy conversion between concrete types and the enum. ```rust use enum_dispatch::enum_dispatch; // Define concrete types struct LinearKnob { position: f64 } struct LogarithmicKnob { position: f64 } // Implement trait for concrete types impl KnobControl for LinearKnob { fn set_position(&mut self, value: f64) { self.position = value; } fn get_value(&self) -> f64 { self.position } } impl KnobControl for LogarithmicKnob { fn set_position(&mut self, value: f64) { self.position = value; } fn get_value(&self) -> f64 { (self.position + 1.).log2() } } // Register trait with enum_dispatch #[enum_dispatch(KnobControl)] enum Knob { LinearKnob, LogarithmicKnob, } // Link trait to registered enum #[enum_dispatch] trait KnobControl { fn set_position(&mut self, value: f64); fn get_value(&self) -> f64; } fn main() { // Automatic From implementations allow easy conversion let mut knob: Knob = LinearKnob { position: 0.5 }.into(); knob.set_position(0.75); assert_eq!(knob.get_value(), 0.75); // Works with any variant let mut log_knob: Knob = LogarithmicKnob { position: 1.0 }.into(); assert_eq!(log_knob.get_value(), 1.0); } ``` -------------------------------- ### Implement Trait with Multiple Methods using Enum Dispatch (Rust) Source: https://context7.com/antonok/enum_dispatch/llms.txt This snippet shows how to use enum_dispatch to implement a trait with various methods (including those with arguments, mutable receivers, and by-value consumption) for multiple structs via an enum. It demonstrates calling trait methods through the enum and unwrapping back to concrete types. ```rust use enum_dispatch::enum_dispatch; use core::convert::TryInto; #[enum_dispatch(Traited)] trait TestTrait { fn describe(&self) -> char; fn default_impl(&self) -> Vec { vec![0, 1, 2, 3] // Default implementations work } fn has_args(&self, arg1: usize, arg2: &str) -> String; fn mutable(&mut self, argument: f32); fn self_by_value(self, argument: f32) -> f32; } struct A; struct B; struct C { custom_string: String, custom_number: f64 } impl TestTrait for A { fn describe(&self) -> char { 'A' } fn has_args(&self, arg1: usize, arg2: &str) -> String { format!("A{},{}", arg1, arg2) } fn mutable(&mut self, _argument: f32) {} fn self_by_value(self, argument: f32) -> f32 { argument + 1. } } impl TestTrait for B { fn describe(&self) -> char { 'B' } fn default_impl(&self) -> Vec { vec![0, 1, 2, 3, 4] } fn has_args(&self, arg1: usize, arg2: &str) -> String { format!("B{},{}", arg1, arg2) } fn mutable(&mut self, _argument: f32) {} fn self_by_value(self, argument: f32) -> f32 { argument + 2. } } impl TestTrait for C { fn describe(&self) -> char { 'C' } fn has_args(&self, arg1: usize, arg2: &str) -> String { format!("C{},{}", arg1, arg2) } fn mutable(&mut self, argument: f32) { self.custom_number = argument.into(); } fn self_by_value(self, argument: f32) -> f32 { argument + self.custom_number as f32 } } #[enum_dispatch] enum Traited { A, B, C, } fn main() { let mut a = Traited::from(A); let mut b = Traited::from(B); let mut c = Traited::from(C { custom_string: "test".to_string(), custom_number: 4.2, }); // All trait methods work through the enum assert_eq!(a.describe(), 'A'); assert_eq!(b.default_impl().len(), 5); assert_eq!(c.has_args(42, "param"), "C42,param"); c.mutable(11.0); // By-value methods consume the enum assert_eq!(a.self_by_value(8.2), 9.2); // TryInto for unwrapping back to concrete type let c_enum = Traited::from(C { custom_string: "test".to_string(), custom_number: 5.0, }); let c_concrete: Result = c_enum.try_into(); assert!(c_concrete.is_ok()); } ``` -------------------------------- ### Implement Trait for Multiple Enums with enum_dispatch Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md This demonstrates how to use the `enum_dispatch` attribute to implement a single trait for several enums simultaneously. Ensure all relevant enums are listed within the attribute. ```rust #[enum_dispatch(Widgets, Tools, Gadgets)] trait CommonFunctionality { // ... } ``` -------------------------------- ### Async Trait Support with enum_dispatch in Rust Source: https://context7.com/antonok/enum_dispatch/llms.txt Showcases how enum_dispatch seamlessly integrates with Rust's native async fn in trait feature. This enables asynchronous operations within enums that implement traits, facilitating non-blocking data fetching or other async tasks. ```rust #![feature(async_fn_in_trait)] use enum_dispatch::enum_dispatch; struct DatabaseA; struct DatabaseB; impl DataSource for DatabaseA { async fn fetch_data(&mut self) -> Result { // Simulate async database call Ok(10) } } impl DataSource for DatabaseB { async fn fetch_data(&mut self) -> Result { // Simulate async database call Ok(20) } } #[enum_dispatch] enum DataSourceEnum { DatabaseA, DatabaseB, } #[enum_dispatch(DataSourceEnum)] trait DataSource { async fn fetch_data(&mut self) -> Result; } async fn example() { let mut source_a: DataSourceEnum = DatabaseA.into(); let mut source_b: DataSourceEnum = DatabaseB.into(); let result_a = source_a.fetch_data().await.unwrap(); let result_b = source_b.fetch_data().await.unwrap(); assert_eq!(result_a, 10); assert_eq!(result_b, 20); } ``` -------------------------------- ### Implement Multiple Traits for a Single Enum with enum_dispatch Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md This shows how to apply multiple traits to a single enum using a single `enum_dispatch` attribute. List all desired traits within the attribute to associate them with the enum. ```rust #[enum_dispatch(CommonFunctionality, WidgetFunctionality)] enum Widget { // ... } ``` -------------------------------- ### Generic Trait and Enum Support with Enum Dispatch (Rust) Source: https://context7.com/antonok/enum_dispatch/llms.txt This snippet illustrates how enum_dispatch can be applied to traits and enums that include generic type parameters and lifetimes. This provides flexibility when dealing with parameterized types and ensures that generic constraints are correctly maintained across the trait and the dispatching enum. ```rust use enum_dispatch::enum_dispatch; use std::marker::PhantomData; pub trait Bar {} struct SuperFoo { _bar: T } struct UltraFoo { _bar: T } impl Foo for SuperFoo { fn do_something(&mut self, _val: T) { println!("SuperFoo"); } } impl Foo for UltraFoo { fn do_something(&mut self, _val: T) { println!("UltraFoo"); } } #[enum_dispatch] pub trait Foo { fn do_something(&mut self, val: T); } // Generic parameters must match between trait and enum #[enum_dispatch(Foo)] pub enum AnyFoo { SuperFoo(SuperFoo), UltraFoo(UltraFoo), } // Lifetime parameters also supported struct SuperFaz<'a>(PhantomData<&'a u8>); struct UltraFaz(); impl<'a> Faz for SuperFaz<'a> {} impl Faz for UltraFaz {} #[enum_dispatch] pub trait Faz {} #[enum_dispatch(Faz)] pub enum AnyFaz<'a> { SuperFaz(SuperFaz<'a>), UltraFaz(UltraFaz), } fn main() { use core::convert::TryInto; let anyfaz: AnyFaz = SuperFaz(PhantomData::<&u8>::default()).into(); let superfaz: Result = anyfaz.try_into(); assert!(superfaz.is_ok()); } ``` -------------------------------- ### Handle Generic Enums and Traits with enum_dispatch Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md Illustrates `enum_dispatch`'s capability to work with generic enums and traits. When linking, include the generic parameters in the attribute argument, ensuring they match between the enum and trait definitions. ```rust #[enum_dispatch] trait Foo { /* ... */ } #[enum_dispatch(Foo)] enum Bar { /* ... */ } ``` -------------------------------- ### Register Multiple Traits and Enums with enum_dispatch in Rust Source: https://context7.com/antonok/enum_dispatch/llms.txt Demonstrates registering multiple enums for a single trait or multiple traits for a single enum using the enum_dispatch attribute. This allows for concise implementation of common functionalities across different enum types or specialized behaviors for a single enum. ```rust use enum_dispatch::enum_dispatch; // Implement same trait for multiple enums #[enum_dispatch(Widgets, Tools, Gadgets)] trait CommonFunctionality { fn activate(&self) -> bool; fn deactivate(&mut self); } #[enum_dispatch] enum Widgets { Button, Slider, } #[enum_dispatch] enum Tools { Hammer, Screwdriver, } #[enum_dispatch] enum Gadgets { Phone, Computer, } // Implement multiple traits for single enum #[enum_dispatch(Display, Interactive)] enum Widget { Button, Slider, } #[enum_dispatch] trait Display { fn render(&self) -> String; } #[enum_dispatch] trait Interactive { fn on_click(&mut self); } struct Button { label: String } struct Slider { value: f32 } impl Display for Button { fn render(&self) -> String { format!("Button: {}", self.label) } } impl Interactive for Button { fn on_click(&mut self) { println!("Button clicked"); } } impl Display for Slider { fn render(&self) -> String { format!("Slider: {}", self.value) } } impl Interactive for Slider { fn on_click(&mut self) { println!("Slider adjusted"); } } fn main() { let button: Widget = Button { label: "OK".to_string() }.into(); println!("{}", button.render()); // Display trait let mut slider: Widget = Slider { value: 0.5 }.into(); slider.on_click(); // Interactive trait } ``` -------------------------------- ### Enum Variant Type Handling in enum_dispatch Source: https://gitlab.com/antonok/enum_dispatch/-/blob/master/README.md Explains how `enum_dispatch` restructures enum variants to hold concrete types. It generates a new variant name (typically the type name) and uses the provided type as its sole argument. ```rust enum MyBehaviorEnum { MyImplementorA(MyImplementorA), MyImplementorB(MyImplementorB), } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.