#[macro_export]
macro_rules! integer_choices {
(
$name:ident {
$( $variant:ident = $value:expr, $label:literal ),* $(,)?
}
) => {
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum $name {
$( $variant = $value, )*
}
impl $name {
pub fn label(&self) -> &'static str {
match self {
$( Self::$variant => $label, )*
}
}
pub fn value(&self) -> i32 {
*self as i32
}
pub fn choices() -> Vec<(i32, &'static str)> {
vec![ $( ($value, $label), )* ]
}
}
};
}
#[macro_export]
macro_rules! text_choices {
(
$name:ident {
$( $variant:ident = $value:expr, $label:literal ),* $(,)?
}
) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum $name {
$( $variant, )*
}
impl $name {
pub fn label(&self) -> &'static str {
match self {
$( Self::$variant => $label, )*
}
}
pub fn value(&self) -> &'static str {
match self {
$( Self::$variant => $value, )*
}
}
pub fn choices() -> Vec<(&'static str, &'static str)> {
vec![ $( ($value, $label), )* ]
}
}
};
}
#[cfg(test)]
mod tests {
crate::integer_choices! {
Status {
Draft = 0, "Draft",
Published = 1, "Published",
}
}
crate::text_choices! {
Visibility {
Private = "private", "Private",
Public = "public", "Public",
}
}
#[test]
fn integer_choices_returns_variant_label() {
assert_eq!(Status::Draft.label(), "Draft");
assert_eq!(Status::Published.label(), "Published");
}
#[test]
fn integer_choices_returns_variant_value() {
assert_eq!(Status::Draft.value(), 0);
assert_eq!(Status::Published.value(), 1);
}
#[test]
fn integer_choices_returns_choices_list() {
assert_eq!(Status::choices(), vec![(0, "Draft"), (1, "Published")]);
}
#[test]
fn text_choices_returns_variant_label() {
assert_eq!(Visibility::Private.label(), "Private");
assert_eq!(Visibility::Public.label(), "Public");
}
#[test]
fn text_choices_returns_variant_value() {
assert_eq!(Visibility::Private.value(), "private");
assert_eq!(Visibility::Public.value(), "public");
}
#[test]
fn text_choices_returns_choices_list() {
assert_eq!(
Visibility::choices(),
vec![("private", "Private"), ("public", "Public")]
);
}
}