Lenguajes específicos de dominio (DSLs)

Un DSL es un mini "lenguaje" incrustado en un macro de Rust. Es Rust completamente válido porque el sistema de macros se expande en construcciones normales de Rust, pero parece un lenguaje pequeño. Esto te permite definir una sintaxis concisa o intuitiva para alguna funcionalidad especial (dentro de los límites).

Supongamos que quiero definir una pequeña API de calculadora. Me gustaría proporcionar una expresión e imprimir la salida en la consola.

macro_rules! calcula {
    (eval $e:expr) => {{
        {
            let val: usize = $e; // Fuerza que los tipos sean enteros
            println!("{} = {}", stringify!{$e}, val);
        }
    }};
}

fn main() {
    calcula! {
        eval 1 + 2 // ¡jejeje, `eval` es _no_ una palabra clave de Rust!
    }

    calcula! {
        eval (1 + 2) * (3 / 4)
    }
}

Salida:

1 + 2 = 3
(1 + 2) * (3 / 4) = 0

Este fue un ejemplo muy simple, pero se han desarrollado interfaces mucho más complejas, como lazy_static o clap.

Además, ten en cuenta los dos pares de llaves en la macro. Los externos son parte de la sintaxis de macro_rules!, además de () o [].