MCPcopy Index your code
hub / github.com/AS1100K/pastey

github.com/AS1100K/pastey @v0.2.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.2.3 ↗ · + Follow
275 symbols 313 edges 43 files 105 documented · 38% updated 6d agov0.2.3 · 2026-05-20★ 873 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Macros for all your token pasting needs

github crates.io docs.rs build status

pastey is the fork of paste and is aimed to be a drop-in replacement with additional features for paste crate

Migrating from paste crate

Migrating from paste crate to pastey is super simple, just change the following in your Cargo.toml

[dependencies]
- paste = "1"
+ pastey = "*" # Or any specific version of pastey

Or even better way:

[dependencies]
- paste = "1"
+ paste = { package = "pastey", version = "*" }

Quick Start

Add pastey as your dependency in Cargo.toml

[dependencies]
# TODO: Replace with latest version available on crates.io
pastey = "*"

This approach works with any Rust compiler 1.54+.

Pasting identifiers

Within the paste! macro, identifiers inside [<...>] are pasted together to form a single identifier.

use pastey::paste;

paste! {
    // Defines a const called `QRST`.
    const [<Q R S T>]: &str = "success!";
}

fn main() {
    assert_eq!(
        paste! { [<Q R S T>].len() },
        8,
    );
}

More elaborate example

The next example shows a macro that generates accessor methods for some struct fields. It demonstrates how you might find it useful to bundle a paste invocation inside of a macro_rules macro.

use pastey::paste;

macro_rules! make_a_struct_and_getters {
    ($name:ident { $($field:ident),* }) => {
        // Define a struct. This expands to:
        //
        //     pub struct S {
        //         a: String,
        //         b: String,
        //         c: String,
        //     }
        pub struct $name {
            $(
                $field: String,
            )*
        }

        // Build an impl block with getters. This expands to:
        //
        //     impl S {
        //         pub fn get_a(&self) -> &str { &self.a }
        //         pub fn get_b(&self) -> &str { &self.b }
        //         pub fn get_c(&self) -> &str { &self.c }
        //     }
        paste! {
            impl $name {
                $(
                    pub fn [<get_ $field>](&self) -> &str {
                        &self.$field
                    }
                )*
            }
        }
    }
}

make_a_struct_and_getters!(S { a, b, c });

fn call_some_getters(s: &S) -> bool {
    s.get_a() == s.get_b() && s.get_c().is_empty()
}
let s = S {
    a: String::from("x"),
    b: String::from("x"),
    c: String::new(),
 };
 assert!(call_some_getters(&s));
 let s2 = S {
     a: String::from("x"),
     b: String::from("y"),
     c: String::new(),
 };
 assert!(!call_some_getters(&s2));

Case conversion

The pastey crate supports the following case modfiers:

Modifier Description
$var:lower Lower Case
$var:upper Upper Case
$var:snake Snake Case
$var:camel or $var:upper_camel Upper Camel Case
$var:lower_camel Lower Camel Case #4
$var:camel_edge Covers Edge cases of Camel Case. #3

NOTE: The pastey crate is going to be a drop in replacement to paste crate, and will not change the behaviour of existing modifier like lower, upper, snake and camel. For modifying the behaviour new modifiers will be created, like camel_edge

You can also use multiple of these modifers like $var:snake:upper would give you SCREAMING_SNAKE_CASE.

Example

use pastey::paste;

paste! {
    const [<LIB env!("CARGO_PKG_NAME"):snake:upper>]: &str = "libpastey";

    let _ = LIBPASTEY;
}

The precise Unicode conversions are as defined by [str::to_lowercase] and [str::to_uppercase].

Replace modifier

The replace modifier allows you to perform string replacement on identifiers, using the same semantics as [str::replace]. This is useful for transforming identifiers by removing or substituting substrings.

use pastey::paste;

macro_rules! m {
    ($(($command:ident, $from:ident)),+) => {
        paste! {
            $(pub struct $command {})*

            pub enum Command {
                $(
                    [< $command:replace($from, "") >] ( $command )
                ),*
            }
        }
    }
}

m! {
    (CommandFoo, Command),
    (CommandBar, Command),
    (HelloWorld, Hello)
}

let command_bar = Command::Bar(CommandBar {});
let command_foo = Command::Foo(CommandFoo {});
let command_hello = Command::World(HelloWorld {});

Raw Identifier Generation

pastey now supports raw identifiers using a special raw mode. By prefixing a token with # inside the paste syntax, it treats that token as a raw identifier.

use pastey::paste;

macro_rules! define_struct_and_impl {
    ($name:ident $(- $name_tail:ident)*) => {
        paste!{
            struct [< # $name:camel $( $name_tail)* >]; // '#' signals a raw identifier

            impl [< # $name:camel $( $name_tail)* >] {
                fn [< # $name:snake $( _ $name_tail:snake)* >]() {}
            }

        }
    }
}

define_struct_and_impl!(loop);
define_struct_and_impl!(loop - xyz);

fn test_fn() {
    let _ = Loop::r#loop();
    let _ = Loopxyz::loop_xyz();
}
test_fn();

Pasting documentation strings

Within the paste! macro, arguments to a #[doc ...] attribute are implicitly concatenated together to form a coherent documentation string.

use pastey::paste;

macro_rules! method_new {
    ($ret:ident) => {
        paste! {
            #[doc = "Create a new `" $ret "` object."]
            pub fn new() -> $ret { $ret {} }
        }
    };
}

pub struct Pastey {}

method_new!(Pastey);  // expands to #[doc = "Create a new `Paste` object"]
let _ = new();

Credits

This crate is the fork of paste and I appreciate the efforts of @dtolnay and other contributors.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Extension points exported contracts — how you extend this code

Trait (Interface)
(no doc) [1 implementers]
paste-compat/tests/test_expr.rs
Trait (Interface)
(no doc) [1 implementers]
pastey-test-suite/tests/test_expr.rs

Core symbols most depended-on inside this repo

parse_bracket_as_segments
called by 9
src/lib.rs
expand
called by 7
src/lib.rs
expand_attr
called by 5
src/attr.rs
get_token_tree_string_value
called by 4
src/segment.rs
paste
called by 4
src/lib.rs
pasted_to_tokens
called by 3
src/lib.rs
parse
called by 2
src/segment.rs
get_literal_string_value
called by 2
src/segment.rs

Shape

Function 247
Class 14
Method 9
Enum 3
Interface 2

Languages

Rust100%

Modules by API surface

src/lib.rs83 symbols
src/segment.rs34 symbols
pastey-test-suite/tests/test_expr.rs30 symbols
pastey-test-suite/tests/test_attr.rs30 symbols
pastey-test-suite/tests/test_item.rs21 symbols
paste-compat/tests/test_expr.rs17 symbols
src/attr.rs11 symbols
pastey-test-suite/tests/test_doc.rs6 symbols
src/error.rs4 symbols
paste-compat/tests/basic.rs4 symbols
pastey-test-suite/build.rs3 symbols
src/test_helpers.rs2 symbols

For agents

$ claude mcp add pastey \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact