Created
September 5, 2018 00:22
-
-
Save eaglgenes101/9ec7c7bb80e0c7bd7ff6e43540722795 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
macro_rules! self_match { | |
($token:ident) => { | |
( & $token, & $token ) | |
} | |
} | |
macro_rules! jump_table_impl { | |
( | |
$name:ident : $fntype:ty { | |
$( $variant:ident = $value:expr ) ,* | |
} | |
) => { | |
use std::convert::From; | |
use std::fmt::{Error, Formatter, Debug, Display}; | |
use std::cmp::{PartialEq, Eq}; | |
use std::marker::{Copy, Clone}; | |
impl Copy for $name {} | |
impl Clone for $name { | |
fn clone(&self) -> Self { | |
*self | |
} | |
} | |
impl Eq for $name {} | |
impl PartialEq for $name { | |
fn eq(&self, other: &Self) -> bool { | |
match (self, other) { | |
$( self_match!($variant) => true, ) * | |
_ => false | |
} | |
} | |
} | |
impl From< $name > for $fntype { | |
fn from( val: $name ) -> Self { | |
match val { | |
$( $variant => $value ), * | |
} | |
} | |
} | |
impl Debug for $name { | |
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { | |
let disp_str = match self { | |
$( $variant => stringify!( $variant )), + | |
}; | |
f.write_str(disp_str) | |
} | |
} | |
impl Display for $name { | |
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { | |
let disp_str = match self { | |
$( $variant => stringify!( $variant )), + | |
}; | |
f.write_str(disp_str) | |
} | |
} | |
}; | |
} | |
#[macro_export] | |
macro_rules! jump_table { | |
( | |
enum $name:ident : $fntype:ty { | |
$( $variant:ident = $value:expr ) , * | |
} | |
) => { | |
enum $name { | |
$( $variant , ) * | |
} | |
jump_table_impl!( | |
$name : $fntype { | |
$( $variant = $value , ) * | |
} | |
); | |
}; | |
} | |
#[cfg(test)] | |
mod tests { | |
fn one() -> &'static str { | |
"one" | |
} | |
fn two() -> &'static str { | |
"two" | |
} | |
fn three() -> &'static str { | |
"three" | |
} | |
jump_table!( | |
enum Thing: fn() -> &'static str { | |
One = one, | |
Two = two, | |
Three = three | |
} | |
); | |
#[test] | |
fn expansion_test() { | |
let thing_fn: fn() -> &'static str = Thing::One.into(); | |
assert!(thing_fn() == "one"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment