2 releases

0.0.2 May 18, 2021
0.0.1 May 17, 2021

#1653 in Procedural macros

MIT license

10KB
109 lines

ctjs

Execute JavaScript at compile time to generate Rust code. Both evaluating expressions and custom derives are supported.

eval

use ctjs::eval;

const X: f64 = eval! {
  // This is JavaScript
  const x = 5;
  String(x * Math.PI)
};

assert!(X > 15.0);
assert!(X < 16.0);

Custom Derive

use ctjs::JsMacro;

#[derive(Debug, JsMacro)]
#[js_macro = "fruit_derive"]
enum Fruit {
    #[js(name = "granny smith")]
    Apple,
    Orange,
    Pear,
}

fruit_derive! {
    js!(
        let output = "const _: () = {\n";
        output += "use std::fmt::{self, Write};\n";
        // name is "Fruit"
        output += "impl fmt::Display for " + name + "{\n";
        output += "fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n";
        output += "write!(f, \"{}\", match self {\n";
        // ident is "Apple" or "Orange" or "Pear"
        for (const { ident, attrs } of item.variants) {
            let string = '"' + ident.toLowerCase() + '"';
            const kv = ctjs.parse_attrs(attrs);
            if (kv.name) {
                string = kv.name;
            }

            output += "Self::" + ident + " => " + string + ",\n";
        }
        output += "})\n";
        output += "}\n}\n};\n";
        output
    )
}

let fruits = vec![Fruit::Apple, Fruit::Orange, Fruit::Pear];
for fruit in &fruits {
    println!("Debug: {:?}, Display: {}", fruit, fruit);
}

assert_eq!(&fruits[0].to_string(), "granny smith");
assert_eq!(&fruits[1].to_string(), "orange");
assert_eq!(&fruits[2].to_string(), "pear");

Current version: 0.0.1

Prior Work

All code licensed as MIT

Dependencies

~5MB
~134K SLoC