Home

Published on: Mon Mar 10 2025

Introducing pastey

Reddit Post GitHub Repo

I am excited to introduce pastey, a drop-in replacement for the now-archived paste crate. Recently, the paste crate was archived i.e. it will not be maintained anymore. And since, there were no good alternative available for paste, I felt I need to step in and fork the repository and further maintain it.

However, I do not merely intend to fork the repository; I aim to demonstrate my commitment to improving the code by fixing existing bugs and issues before releasing pastey.

A Drop-in Replacement

The main goal of pastey is to maintain the same behavior as the original paste crate, ensuring it functions as a drop-in replacement.

Since, paste is a perfectly built there are not going to be any internal design changes (at least for now). Therefore, for new behaviour additional modifiers are created for some other uses case. More on that at Additional Features Section.

I have built a special test suite named paste-compat that ensures the behaviour of pastey is similar to paste crate for common modifiers and features.

Currently, more tests are welcomed for paste-compat.

Migrating from paste crate

It is very easy to migrate from paste crate to pastey, follow either of the following steps:

[dependencies]
- paste = "1"
+ pastey = "*" # Or replace with the latest version of pastey

Or even better:

[dependencies]
- paste = "1"
+ paste = { package = "pastey", version = "*" }  # Or replace with the latest version of pastey

You might go with this step, if you don’t want to rename every paste:: with pastey::

Additional Features

The pastey crate also comes with additional features:

  • Raw Identifier Generation: The pastey crate supports a raw mode in paste! to generate raw identifiers, like loop. The following example shows how it’s used:

    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();
    }
  • camel_edge: The camel_edge modifier addresses an edge case in camel case conversion. For example, while the existing camel modifier converts both my__ident and _my__ident to MyIdent, this behavior can be problematic if they are meant to be distinct. With camel_edge

    1. my__ident is converted to My_Ident
    2. _my__ident is converted to _My_Ident

    More Info

  • lower_camel: The lower_camel modifier is a variation of camel case conversion that makes the first letter lowercase instead of uppercase.

    More Info

I know that these modifiers break the rust naming convention, but can be useful for some internal crates dealing with FFI or other use cases.