macro_rules! declare_types {
($($token:ident -> $inner:ty, $to_string:expr,)*) => {
enum Value {
$($token($inner),)*
}
impl Display for Value {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
match self {
$(
Self::$token(inner)=>write!(fmt,"{}",$to_string)?,
)*
};
Ok(())
}
}
}
}
declare_types!(
String -> String, inner,
);
However, the code results in a compiler error:
cannot find value `inner` in this scope
not found in this scope
When I hover onto inner
, IDE shows it properly:
Also, by expanding the macro and pasting it back, it works without any errors.
Because of macro hygiene, identifiers created inside the macro (like inner
in Self::$token (inner)
) are different from identifiers created in the calling code (like inner
in declare_types!(String -> String, inner);
). If you want to be able to use an identifier in the displayed expression, you will need to pass this identifier to the macro from the caller:
macro_rules! declare_types {
($($token:ident -> $inner:ty, $id: ident, $to_string:expr,)*) => {
enum Value {
$($token($inner),)*
}
impl std::fmt::Display for Value {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
$(
Self::$token($id)=>write!(fmt,"{}",$to_string)?,
)*
};
Ok(())
}
}
}
}
declare_types!(
String -> String, inner, inner,
);