genco 0.12.0

A whitespace-aware quasiquoter for beautiful code generation.
Documentation

Build Status crates.io docs.rs

genco

A whitespace-aware quasiquoter for beautiful code generation.

Central to genco are the quote! and quote_in! procedural macros which ease the construction of token streams.

This project solves the following language-specific concerns:

  • Imports — Generates and groups import statements as they are used. What you use is what you get with no redundancy and consistency. We also do our best to solve namespace conflicts for you.

  • String Quoting — genco knows how to quote strings. And can even interpolate values into the quoted string if it's supported by the language.

  • Structural Indentation — The quoter relies on intuitive whitespace detection to structurally sort out spacings and indentation. Allowing genco to generate beautiful readable code with minimal effort. This is also a requirement for generating correctly behaving code in languages like Python where indentation is meaningful.

  • Language Customization — Building support for new languages is a piece of cake with the help of the impl_lang! macro.

To do whitespace detection, we depend on the proc_macro_span feature.

Until this is stabilized, you must build and run projects using genco with the nightly compiler.

cargo +nightly run --example rust

Supported Languages

The following are languages which have built-in support in genco. Is your favorite language missing? Open an issue!

You can run one of the examples using:

cargo run --example go

Rust Example

The following is a simple program producing Rust code to stdout with custom configuration:

use genco::prelude::*;
use genco::fmt;

let map = rust::import("std::collections", "HashMap");

let tokens: rust::Tokens = quote! {
    fn main() {
        let mut m = #map::new();
        m.insert(1u32, 2u32);
    }
};

let stdout = std::io::stdout();
let mut w = fmt::IoWriter::new(stdout.lock());

let fmt = fmt::Config::from_lang::<Rust>()
    .with_indentation(fmt::Indentation::Space(2));
let config = rust::Config::default();

tokens.format_file(&mut w.as_formatter(fmt), &config)?;

This would produce:

use std::collections::HashMap;

fn main() {
    let mut m = HashMap::new();
    m.insert(1u32, 2u32);
}