Skip to content

Instantly share code, notes, and snippets.

@eaglgenes101
Created September 5, 2018 00:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eaglgenes101/5077d0420e0f0fca06da8540156522db to your computer and use it in GitHub Desktop.
Save eaglgenes101/5077d0420e0f0fca06da8540156522db to your computer and use it in GitHub Desktop.
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