pastey
A maintained fork of the paste crate for compile-time identifier concatenation, with raw identifiers and a string-replace modifier built in.
Repository Health
Technical Analysis
Pastey provides the paste! procedural macro, which lets Rust macros paste tokens together inside [< ... >] to form a brand-new identifier at compile time. This is the trick declarative macros need to generate names like get_field from a field identifier, build enum variants from a list of idents, or assemble a struct and its accessor methods in one macro_rules! expansion — something the Rust macro system cannot do on its own.
Pastey is a fork of the widely used but now-archived dtolnay/paste crate, built as a drop-in replacement (paste = { package = "pastey" }) so existing code keeps working unchanged. On top of the original feature set it adds a :replace(from, to) modifier for substring substitution on pasted segments, raw identifier generation via a # prefix for names that collide with keywords, a :camel_edge modifier for tricky camelCase conversions, and active CI against current Rust toolchains where the upstream crate has gone quiet.
What You Get
- The
paste!macro for compile-time identifier concatenation inside[< ... >] - Case conversion modifiers:
:lower,:upper,:snake,:camel/:upper_camel,:lower_camel,:camel_edge, chainable like:snake:upper - A
:replace(from, to)modifier forstr::replace-style substitution on identifier segments - Raw identifier generation via a
#prefix inside[< ... >]for names that collide with keywords - Implicit concatenation of
#[doc = ...]attribute arguments for building doc strings dynamically - Drop-in compatibility with the archived
pastecrate via a package rename in Cargo.toml
Common Use Cases
- Generating getter/setter methods for struct fields inside a
macro_rules!macro - Deriving enum variant names from macro input idents, stripping shared prefixes with
:replace - Migrating off the unmaintained upstream
pastecrate with a one-line Cargo.toml change - Building documentation strings dynamically for macro-generated items
Under The Hood
Architecture
The crate is a single proc-macro library (src/lib.rs) exposing paste! (plus doc-hidden item!/expr! aliases) that recursively walks the input TokenStream, splitting on groups/idents/puncts and delegating bracketed [< ... >] content to segment.rs (tokenizing into a Segment enum: String/Apostrophe/Env/Modifier/Replace) and attribute-position pasting to attr.rs’s expand_attr, with error.rs providing a small typed Error/Result that emits compile_error! tokens on failure. The layering is flat but clean: lib.rs owns token-tree recursion, segment.rs owns segment parsing and pasting, attr.rs owns attribute-specific recursion, joined by shared error types. Data flows one directionally — raw TokenStream in, recursive expand() walk, per-bracket parse_bracket_as_segments(), segment::parse/segment::paste, pasted_to_tokens() back out — with no runtime state since it executes entirely at compile time in each call site’s crate.
Tech Stack
A pure proc-macro = true crate with zero runtime dependencies, using only std and the compiler-provided proc_macro API (TokenStream, TokenTree, Ident, Literal, Group, Punct, Span), targeting edition 2018 with an MSRV of 1.54. The workspace has two auxiliary members: paste-compat, a compatibility shim, and pastey-test-suite, the actual test harness. CI runs the test matrix across nightly/beta/stable/1.56.0 Rust plus a dedicated MSRV 1.54 check, a cargo docs-rs doc build, clippy --tests -Dclippy::all -Dclippy::pedantic, Miri, and a coverage job, all driven by a test.sh script and reusable dtolnay/.github workflows. No build tooling beyond Cargo; it ships to crates.io as pastey.
Code Quality
Tests live in the separate pastey-test-suite workspace member: test_item.rs, test_expr.rs, test_attr.rs, test_doc.rs, and a compiletest.rs driving dozens of trybuild-style compile-fail fixtures under tests/ui/*.rs with matching .stderr files, giving explicit coverage of error paths like invalid identifiers, unsupported literals, and raw-mode edge cases. Error handling is explicit and typed rather than panic-based, converting failures into compile_error! output, and the source carries unusually thorough inline comments explaining why certain branches are provably unreachable. A #[cfg(coverage_nightly)]-gated test-helper module exists purely to reach coverage on otherwise-unreachable paths. CI enforces -Dwarnings, pedantic Clippy, and Miri for undefined-behavior detection alongside the MSRV check.
API Design
The public surface is deliberately small — one macro (paste!) with a bracket syntax and a handful of chainable modifiers — which keeps the learning curve low for a proc-macro crate. Migrating from the original paste crate needs a single Cargo.toml line change, and the README documents every modifier with a runnable example, making the added :replace and raw-identifier features easy to discover without reading source.
Used by 2 apps in this directory
QuestDB
Databases · Analytics
A high-performance, open-source time-series database built for financial market data, IoT telemetry, and real-time analytics, combining a zero-GC Java/C++ core with SIMD-accelerated SQL and a WAL-to-Parquet storage engine.
Vaultwarden
Password Manager · Security
Unofficial Bitwarden-compatible server in Rust — run the full Bitwarden ecosystem on a Raspberry Pi using every official client you already have, without the multi-container overhead.