Skip to content

Instantly share code, notes, and snippets.

@AnthonyMikh
Created February 5, 2021 16:58
Show Gist options
  • Save AnthonyMikh/5f2b0a4cfcb12fc865bba181672c9dc5 to your computer and use it in GitHub Desktop.
Save AnthonyMikh/5f2b0a4cfcb12fc865bba181672c9dc5 to your computer and use it in GitHub Desktop.
Macro for creating auto-enumerated constants in Golang's iota-like way
macro_rules! iota_consts {
(
$iota:ident: $($tt:tt)*
) => {
iota_consts!(
$iota(0, $iota): $($tt)*
);
};
(
$iota:ident($iota_value:expr, $prev_expr:expr):
$(#[$attr:meta])*
$vis:vis
const $name:ident : $ty:ty;
$($tt:tt)*
) => {
$(#[$attr])*
$vis
const $name: $ty = {
#[allow(dead_code, non_upper_case_globals)]
const $iota: $ty = $iota_value;
$prev_expr
};
iota_consts!(
$iota($iota_value + 1, $prev_expr):
$($tt)*
);
};
(
$iota:ident($iota_value:expr, $prev_expr:expr):
$(#[$attr:meta])*
$vis:vis
static $name:ident : $ty:ty;
$($tt:tt)*
) => {
$(#[$attr])*
$vis
static $name: $ty = {
#[allow(dead_code, non_upper_case_globals)]
const $iota: $ty = $iota_value;
$prev_expr
};
iota_consts!(
$iota($iota_value + 1, $prev_expr):
$($tt)*
);
};
(
$iota:ident($iota_value:expr, $prev_expr:expr):
$(#[$attr:meta])*
$vis:vis
static mut $name:ident : $ty:ty;
$($tt:tt)*
) => {
$(#[$attr])*
$vis
static mut $name: $ty = {
#[allow(dead_code, non_upper_case_globals)]
const $iota: $ty = $iota_value;
$prev_expr
};
iota_consts!(
$iota($iota_value + 1, $prev_expr):
$($tt)*
);
};
(
$iota:ident($iota_value:expr, $prev_expr:expr):
$(#[$attr:meta])*
$vis:vis
const $name:ident : $ty:ty = $const_value:expr;
$($tt:tt)*
) => {
$(#[$attr])*
$vis
const $name: $ty = {
#[allow(dead_code, non_upper_case_globals)]
const $iota: $ty = $iota_value;
$const_value
};
iota_consts!(
$iota($iota_value + 1, $const_value):
$($tt)*
);
};
(
$iota:ident($iota_value:expr, $prev_expr:expr):
$(#[$attr:meta])*
$vis:vis
static $name:ident : $ty:ty = $const_value:expr;
$($tt:tt)*
) => {
$(#[$attr])*
$vis
static $name: $ty = {
#[allow(dead_code, non_upper_case_globals)]
const $iota: $ty = $iota_value;
$const_value
};
iota_consts!(
$iota($iota_value + 1, $const_value):
$($tt)*
);
};
(
$iota:ident($iota_value:expr, $prev_expr:expr):
$(#[$attr:meta])*
$vis:vis
static mut $name:ident : $ty:ty = $const_value:expr;
$($tt:tt)*
) => {
$(#[$attr])*
$vis
static mut $name: $ty = {
#[allow(dead_code, non_upper_case_globals)]
const $iota: $ty = $iota_value;
$const_value
};
iota_consts!(
$iota($iota_value + 1, $const_value):
$($tt)*
);
};
(
$iota:ident($iota_value:expr, $prev_expr:expr):
_;
$($tt:tt)*
) => {
iota_consts!(
$iota($iota_value + 1, $prev_expr):
$($tt)*
);
};
(
$iota:ident($iota_value:expr, $prev_expr:expr):
) => {};
}
iota_consts!(iota:
const FOO: u32 = 1 << iota; // iota = 0, FOO = 1
static BAR: i32; // iota = 1, BAR = 2
_; // iota = 2
#[allow(dead_code)]
static mut BAZ: i8 = iota + 2; // iota = 3, BAZ = 5
const QUX: i16; // iota = 4, QUX = 6
);
macro_rules! print_consts {
($($name:ident),*) => {
$(println!("{} = {}", stringify!($name), $name);)*
};
}
fn main() {
print_consts! {
FOO,
BAR,
/* BAZ */
QUX
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment