Skip to content

Instantly share code, notes, and snippets.

@ruescasd
Created October 2, 2025 21:38
Show Gist options
  • Select an option

  • Save ruescasd/264b3d35717d22db21c056f54013833a to your computer and use it in GitHub Desktop.

Select an option

Save ruescasd/264b3d35717d22db21c056f54013833a to your computer and use it in GitHub Desktop.
#[enum_dispatch(Machine1Handler)]
enum Machine1 {
Machine1StateA,
Machine1StateB,
}
impl Machine1 {
pub fn handle_input(&self, input: &Machine1Input) {
// even if we were to name the trait functions with the same name, we can disambiguate them like this
// otherwise we could simply call input.boomerang(self)
Machine1Boomerang::boomerang(input, &self);
}
}
struct Machine1StateA;
impl Machine1Handler for Machine1StateA {
// this wouldn't be here, it's just a way to show who is handling input
fn name(&self) -> String { "Machine1StateA".to_string() }
}
struct Machine1StateB;
impl Machine1Handler for Machine1StateB {
// this wouldn't be here, it's just a way to show who is handling input
fn name(&self) -> String { "Machine1StateB".to_string() }
}
#[enum_dispatch(Machine2Handler)]
enum Machine2 {
Machine2StateA,
Machine2StateB,
}
impl Machine2 {
pub fn handle_input(&self, input: &Machine2Input) {
// even if we were to name the trait functions with the same name, we can disambiguate them like this
// otherwise we could simply call input.boomerang(self)
Machine2Boomerang::boomerang(input, &self);
}
}
struct Machine2StateA;
impl Machine2Handler for Machine2StateA {
// this wouldn't be here, it's just a way to show who is handling input
fn name(&self) -> String { "Machine2StateA".to_string() }
}
struct Machine2StateB;
impl Machine2Handler for Machine2StateB {
// this wouldn't be here, it's just a way to show who is handling input
fn name(&self) -> String { "Machine2StateB".to_string() }
}
#[enum_dispatch]
trait Machine1Handler {
// shows how the two machines can handle common input
fn handle_common(&self, s: &CommonInput) {
println!("Machine 1 {} handling common with value {}", self.name(), s.0);
}
// this wouldn't be here, it's just a way to show who is handling input
fn name(&self) -> String;
}
#[enum_dispatch]
trait Machine2Handler {
// shows how the two machines can handle common input
fn handle_common(&self, s: &CommonInput) {
println!("Machine2 state {} handling common with value {}", self.name(), s.0);
}
// this wouldn't be here, it's just a way to show who is handling input
fn name(&self) -> String;
}
#[enum_dispatch]
trait Machine1Boomerang {
fn boomerang(&self, s: &Machine1);
}
#[enum_dispatch]
trait Machine2Boomerang {
fn boomerang(&self, s: &Machine2);
}
#[enum_dispatch(Machine1Boomerang)]
enum Machine1Input {
Machine1InputA,
Machine1InputB,
CommonInput,
}
#[enum_dispatch(Machine2Boomerang)]
enum Machine2Input {
Machine2InputA,
Machine2InputB,
CommonInput,
}
struct Machine1InputA;
struct Machine1InputB;
struct Machine2InputA;
struct Machine2InputB;
struct CommonInput(u32);
impl Machine1Boomerang for Machine1InputA {
fn boomerang(&self, s: &Machine1) {
println!("Machine1InputA: boomerang");
}
}
impl Machine1Boomerang for Machine1InputB {
fn boomerang(&self, s: &Machine1) {
println!("Machine1InputB: boomerang");
}
}
impl Machine1Boomerang for CommonInput {
fn boomerang(&self, s: &Machine1) {
println!("CommonInput: machine 1 boomerang");
s.handle_common(self);
}
}
impl Machine2Boomerang for Machine2InputA {
fn boomerang(&self, s: &Machine2) {
println!("Machine2InputA: boomerang");
}
}
impl Machine2Boomerang for Machine2InputB {
fn boomerang(&self, s: &Machine2) {
println!("Machine2InputB: boomerang");
}
}
impl Machine2Boomerang for CommonInput {
fn boomerang(&self, s: &Machine2) {
println!("CommonInput: machine 2 boomerang");
s.handle_common(self);
}
}
fn test() {
let input = Machine1Input::Machine1InputA(Machine1InputA);
let machine1 = Machine1::Machine1StateA(Machine1StateA);
machine1.handle_input(&input);
let input = Machine2Input::Machine2InputA(Machine2InputA);
let machine2 = Machine2::Machine2StateA(Machine2StateA);
machine2.handle_input(&input);
let common = CommonInput(1);
machine1.handle_input(&Machine1Input::CommonInput(common));
let common = CommonInput(2);
machine2.handle_input(&Machine2Input::CommonInput(common));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment