dodo-bindgen-codegen 2.0.0

TypeScript codegen for dodo_bindgen
Documentation
use std::cell::RefCell;

use proc_macro2::Ident;
pub use quote::{ToTokens, format_ident, quote};

thread_local! {
    static RAW: RefCell<Vec<String>> = const { RefCell::new(Vec::new()) };
}

pub fn raw(text: impl Into<String>) -> Ident {
    RAW.with_borrow_mut(|raw| {
        raw.push(text.into());
        format_ident!("__dodo_raw_{}__", raw.len() - 1)
    })
}

pub fn expand_raw(mut source: String) -> String {
    RAW.with_borrow(|raw| {
        for (i, text) in raw.iter().enumerate().rev() {
            let placeholder = format!("__dodo_raw_{i}__");
            if source.contains(&placeholder) {
                source = source.replace(&placeholder, text);
            }
        }
    });
    source
}

#[cfg(test)]
pub fn deno_fmt(source: String) -> String {
    use std::io::Write;
    use std::process::{Command, Stdio};

    let mut child = Command::new("deno")
        .args(["fmt", "--ext", "ts", "-"])
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()
        .expect("failed to spawn `deno fmt`, is deno on PATH?");
    child
        .stdin
        .take()
        .unwrap()
        .write_all(expand_raw(source).as_bytes())
        .unwrap();
    let output = child.wait_with_output().unwrap();
    assert!(
        output.status.success(),
        "deno fmt failed:\n{}",
        String::from_utf8_lossy(&output.stderr)
    );
    String::from_utf8(output.stdout).unwrap()
}