codespace
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;
use quote;
let mut cs = default;
cs.add_item;
cs.add_item;
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.