Skip to content

Instantly share code, notes, and snippets.

@roosmaa
Created August 19, 2015 21:11
Show Gist options
  • Save roosmaa/97342c0acac950db2ea1 to your computer and use it in GitHub Desktop.
Save roosmaa/97342c0acac950db2ea1 to your computer and use it in GitHub Desktop.
Composing and using enums from different modules in Rust
// This is an attempt to figure out a way to compose and use enums
// from different modules interchangebly. Main use-case would be
// when enums are used for messaging.
mod event {
pub trait AnEvent<T> {
fn make(T) -> Self;
fn get(self) -> Option<T>;
}
}
// UI module could be for manipulating user-interfaces
mod ui {
use event::AnEvent;
#[derive(Copy,Clone,Debug)]
pub enum Event {
Tap,
Drag,
}
impl AnEvent<Event> for Event {
fn make(event: Event) -> Event {
event
}
fn get(self) -> Option<Event> {
Some(self)
}
}
}
// Game module could be for some game logic
mod game {
use event::AnEvent;
#[derive(Copy,Clone,Debug)]
pub enum Event {
Hit,
Move,
}
impl AnEvent<Event> for Event {
fn make(event: Event) -> Event {
event
}
fn get(self) -> Option<Event> {
Some(self)
}
}
pub fn get_hit<T>() -> T
where T : AnEvent<Event> {
return T::make(Event::Hit);
}
}
// This is our "app" which could be a game with some nice user interface
// elements. Our event loop needs to deal with events generated in
// either of those modules.
#[derive(Copy,Clone,Debug)]
enum Event {
UI(ui::Event),
Game(game::Event),
}
impl event::AnEvent<Event> for Event {
fn make(event: Event) -> Event {
event
}
fn get(self) -> Option<Event> {
Some(self)
}
}
impl event::AnEvent<ui::Event> for Event {
fn make(event: ui::Event) -> Event {
Event::UI(event)
}
fn get(self) -> Option<ui::Event> {
match self {
Event::UI(event) => Some(event),
_ => None,
}
}
}
impl event::AnEvent<game::Event> for Event {
fn make(event: game::Event) -> Event {
Event::Game(event)
}
fn get(self) -> Option<game::Event> {
match self {
Event::Game(event) => Some(event),
_ => None,
}
}
}
mod talkative {
use {event,game,ui};
// This is some reusable component for handling some parts of the ui and game
// module events.
pub fn say_something<T>(event: T)
where T : event::AnEvent<game::Event> + event::AnEvent<ui::Event> + Copy {
match event.get() {
Some(game::Event::Hit) => println!("Something hit us!"),
Some(game::Event::Move) => println!("We're moving..."),
_ => {
match event.get() {
Some(ui::Event::Tap) => println!("You tapped a button."),
Some(ui::Event::Drag) => println!("Stop dragging me!"),
_ => println!("No idea what just happened..."),
}
},
}
}
}
fn main() {
let events : Vec<Event> = vec![game::get_hit(), Event::UI(ui::Event::Drag)];
for event in events {
talkative::say_something(event);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment