created_at2024-04-20 19:01:09.643077
updated_at2024-04-20 19:01:09.643077
descriptionAttribute-like macros imitating literal prefixes, e.g. #[f]"Hello, {world}"
owners (github:segfaultai:owners)




Important note

This project is currently only an experiment. At this point, it is highly uncertain if the project will be continued or dropped soon.See the on-going discussion on literal prefixes here


Prefixes delivers various prefix-like proc macro attributes for literals to easily create common types.

Quick example:

#![feature(stmt_expr_attributes, proc_macro_hygiene)]

use prefixes::{f, ms, P, s};

fn _deep_thought2() -> String {
    let answer_path = #[P]"./answer.txt";
    let answer = if answer_path.exists() {
    } else {
        std::thread::sleep(#[s]6 + #[ms]9);

    #[f]"Answer to the Ultimate Question of Life, the Universe, and Everything = {answer}"


To use prefixes, first add it to your project in Cargo.toml:

prefixes = "0.1.0"

Then enable stmt_expr_attributes and proc_macro_hygiene features (this is possible only on nightly Rust):

#![feature(stmt_expr_attributes, proc_macro_hygiene)]

Finally, use prefixes that you need, e.g.

#![feature(stmt_expr_attributes, proc_macro_hygiene)]
use prefixes::f;

fn greeting(name: &str) -> String {
    #[f]"Welcome, {name}!"


Prefix #[f]

Build formatted string from a string literal using the format! macro.

#![feature(stmt_expr_attributes, proc_macro_hygiene)]
use prefixes::f;

let n = 2137;
let s1 = format!("n = {n}");
let s2 = #[f]"n = {n}";

assert_eq!(s1, s2);

Might be also useful for creating owned strings, e.g.

#![feature(stmt_expr_attributes, proc_macro_hygiene)]
use prefixes::f;

let s1 = #[f]"2137";
let s2 = "2137".to_string();

assert_eq!(s1, s2);

Prefixes #[ms], #[s]

Build builds std::time::Duration from an integer literal using from_millis (#[ms]) or from_secs[_f32|_f64] methods (#[s]).

#![feature(stmt_expr_attributes, proc_macro_hygiene)]
use std::time::Duration;
use prefixes::{ms, s};

let d1 = Duration::from_millis(1000);
let d2 = #[ms]1000;

assert_eq!(d1, d2);

let d3 = Duration::from_secs(2);
let d4 = #[s]2;

assert_eq!(d3, d4);

let d5 = Duration::from_secs_f32(3.0f32);
let d6 = #[s]3.0f32;

assert_eq!(d5, d6);

let d7 = Duration::from_secs_f64(4.0f64);
let d8 = #[s]4.0f64;

assert_eq!(d7, d8);

Prefixes #[os], #[OS]

Build OsStr (#[os]) or OsString (#[OS]) from a string literal. Additionally, #[OS] supports string interpolation like #[f].

#![feature(stmt_expr_attributes, proc_macro_hygiene)]
use std::ffi::{OsStr, OsString};
use prefixes::{os, OS};

let os1 = OsStr::new("foo");
let os2 = #[os]"foo";

assert_eq!(os1, os2);

let n = 42;
let os3 = OsString::from(format!("n = 42"));
let os4 = #[OS]"n = 42";

assert_eq!(os3, os4);

Prefixes #[p], #[P]

Build Path (#[p]) or PathBuf (#[P]) from a string literal. Additionally, #[P] supports string interpolation.

#![feature(stmt_expr_attributes, proc_macro_hygiene)]
use std::path::{Path, PathBuf};
use prefixes::{p, P};

let p1 = Path::new("/foo");
let p2 = #[p]"/foo";

assert_eq!(p1, p2);

let ext = "txt";
let p3 = PathBuf::from(format!("/foo.{ext}"));
let p4 = #[P]"/foo.{ext}";

assert_eq!(p3, p4);

Prefixes #[re], #[RE]

Build Regex from a string literal. Additionally, #[RE] calls .unwrap() on the result. Works only if regex crate is included in the dependencies. Doesn't require explicit use regex::Regex.

#![feature(stmt_expr_attributes, proc_macro_hygiene)]
use regex::Regex;
use prefixes::{re, RE};

let re1 = Regex::new("1|2");
let re2 = #[re]"1|2";

assert_eq!(format!("{re1:?}"), format!("{re2:?}"));

let re3 = Regex::new("[A-Z]").unwrap();
let re4 = #[RE]"[A-Z]";

assert_eq!(format!("{re3:?}"), format!("{re4:?}"));


This project is licensed under the MIT License - see the LICENSE file for details.

Commit count: 2

cargo fmt