macros - ¿Puede una macro Rust crear nuevos identificadores?
code-generation (2)
Me gustaría crear un par de funciones setter / getter donde los nombres se generan automáticamente en función de un componente compartido, pero no pude encontrar ningún ejemplo de reglas de macro que generen un nuevo nombre.
¿Hay alguna manera de generar código como
fn get_$iden()
y
SomeEnum::XX_GET_$enum_iden
?
Mi caja de
mashup
proporciona una forma estable de crear nuevos identificadores que funcionan con cualquier versión de Rust> = 1.15.0.
#[macro_use]
extern crate mashup;
macro_rules! make_a_struct_and_getters {
($name:ident { $($field:ident),* }) => {
// Define the struct. This expands to:
//
// pub struct S {
// a: String,
// b: String,
// c: String,
// }
pub struct $name {
$(
$field: String,
)*
}
// Use mashup to define a substitution macro `m!` that replaces every
// occurrence of the tokens `"get" $field` in its input with the
// concatenated identifier `get_ $field`.
mashup! {
$(
m["get" $field] = get_ $field;
)*
}
// Invoke the substitution macro to build an impl block with getters.
// This expands to:
//
// impl S {
// pub fn get_a(&self) -> &str { &self.a }
// pub fn get_b(&self) -> &str { &self.b }
// pub fn get_c(&self) -> &str { &self.c }
// }
m! {
impl $name {
$(
pub fn "get" $field(&self) -> &str {
&self.$field
}
)*
}
}
}
}
make_a_struct_and_getters!(S { a, b, c });
No, no a partir de Rust 1.22.
Si puedes usar compilaciones nocturnas ...
Sí:
concat_idents!(get_, $iden)
y eso le permitirá crear un nuevo identificador.
Pero no: el analizador no permite llamadas macro en todas partes, por lo que muchos de los lugares que podría haber intentado hacer esto no funcionarán.
En tales casos, lamentablemente estás solo.
fn concat_idents!(get_, $iden)(…) { … }
, por ejemplo, no funcionará.