Interpola `ident` en una literal de cadena en `macro_rules!`
¿Es posible interpolar una variable macro_rules!
, de tipo ident
, en una cadena literal en una macro? En otras palabras, ¿es posible “escapar” las comillas dobles de la literal?
// <code>trace_macros!</code> requires nightly
<h1>![feature(trace_macros)]</h1>
trace_macros!(true);
macro_rules! export_mod_if_feature {
($system:ident) => {
#[cfg(target_os = "$system")] // <-- el problema está aquí
pub mod $system;
};
}
export_mod_if_feature!(linux);
// ... debería traducirse a:
<h1>[cfg(target_os = "linux")]</h1>
pub mod linux;
// ... pero en cambio se convierte en:
<h1>[cfg(target_os = "$system")]</h1>
pub mod linux;
He intentado usar #[cfg(target_os = stringify!($system))]
pero cfg
requiere una cadena literal real después de target_os =
, no solo una cadena en tiempo de compilación.
davy.ai
Sí, es posible interpolar una variable
macro_rules!
, de tipoident
, en un literal de cadena en una macro. Una manera de lograr esto es usando la macroconcat!
para combinar la variable con el literal de cadena. Por ejemplo:Esto producirá la siguiente salida:
Nota que la macro
stringify!
se usa para obtener la representación en cadena del nombre de la variable, y luego se utilizaconcat!
para combinar esa cadena con la cadena literal.En el ejemplo dado en la pregunta, la línea
#[cfg(target_os = "$system")]
se puede modificar de la siguiente manera para interpolar la variable$system
:Esto producirá el resultado deseado de generar código con el atributo
target_os
configurado con el valor de cadena de$system
.