Created
September 5, 2018 00:49
-
-
Save eaglgenes101/5077d0420e0f0fca06da8540156522db 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! jump_table_copy { | |
( | |
$name:ident { | |
$( $variant:ident ) ,* | |
} | |
) => { | |
use std::marker::{Copy}; | |
impl Copy for $name {} | |
impl Clone for $name { | |
fn clone(&self) -> Self { | |
*self | |
} | |
} | |
}; | |
} | |
macro_rules! jump_table_eq { | |
( | |
$name:ident { | |
$( $variant:ident ) ,* | |
} | |
) => { | |
use std::cmp::{PartialEq, Eq}; | |
impl Eq for $name {} | |
impl PartialEq for $name { | |
fn eq(&self, other: &Self) -> bool { | |
match (self, other) { | |
$( ( & $name::$variant, & $name::$variant ) => true, ) * | |
_ => false | |
} | |
} | |
} | |
} | |
} | |
macro_rules! jump_table_display { | |
( | |
$name:ident { | |
$( $variant:ident ) ,* | |
} | |
) => { | |
use std::fmt::{Error, Formatter, Debug, Display}; | |
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_rules! jump_table_from { | |
( | |
$name:ident : $fntype:ty { | |
$( $variant:ident = $value:expr ) ,* | |
} | |
) => { | |
use std::convert::From; | |
impl From< $name > for $fntype { | |
fn from( val: $name ) -> Self { | |
match val { | |
$( $variant => $value ), * | |
} | |
} | |
} | |
}; | |
} | |
#[macro_export] | |
macro_rules! jump_table { | |
( | |
( #[ $mval:meta ] ) * | |
enum $name:ident : $fntype:ty { | |
$( $variant:ident = $value:expr ) , * | |
} | |
) => { | |
( #[ $mval:meta ] ) * | |
enum $name { | |
$( $variant ), * | |
} | |
jump_table_copy!( | |
$name { | |
$( $variant ), * | |
} | |
); | |
jump_table_eq!( | |
$name { | |
$( $variant ), * | |
} | |
); | |
jump_table_display!( | |
$name { | |
$( $variant ), * | |
} | |
); | |
jump_table_from!( | |
$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