Skip to content

Latest commit

 

History

History
58 lines (44 loc) · 2.59 KB

File metadata and controls

58 lines (44 loc) · 2.59 KB

codespace

codespace on crates.io Documentation (latest release) License

Structural scratch space for generated Rust code

Overview

Code generators that emit raw TokenStreams face a practical problem: a single type definition often requires several top-level items--the struct or enum itself, impl blocks, helper functions, etc. Some of them live together; others live somewhere else entirely (a serde default helper in a defaults module, say). Emitting everything into one flat stream makes related items drift apart; routing some output into separate mods involves annoying bookkeeping.

codespace holds the code during generation. A Codespace owns a tree of Mods; each Mod holds named items (opaque TokenStream fragments) and named (Mod) submodules. Items are added under a "::"-delimited path--intermediate segments name modules; the final segment is a sort key that is never emitted:

use codespace::Codespace;
use quote::quote;

let mut cs = Codespace::default();
cs.add_item("Status", quote! { pub enum Status { Active, Inactive } });
cs.add_item("defaults::status_default", quote! {
    pub fn status_default() -> Status { Status::Active }
});

Adding an item under an existing key appends those tokens, so a type and its impl blocks can accumulate separately and still render together. Each Mod also carries optional metadata: visibility, doc paragraphs, attributes.

Output

Generators can output tokens into a single TokenStream with Codespace::into_stream or into multiple files with Codespace::into_files, where each TokenStream is intended for a particular file path. The former is good for proc macro implementation or calls from a build.rs file; the latter can be well-suited for a stand-alone crate generator.

Both forms are deterministic and unformatted. Callers process the emitted TokenStreams and apply formatting as needed with rustfmt or prettyplease.

codespace never parses, validates, or understands the fragments it holds, and makes no naming decisions. Module names are the exception--invalid names (including Rust keywords) are caller bugs and panic. See the crate docs for details.

Notes

  • Early alpha; API unstable.
  • Part of the typify/progenitor code-generation stack.