2个版本

0.1.1 2024年8月18日
0.1.0 2024年8月18日

#1696过程宏

Download history 150/week @ 2024-08-14

150 每月下载量
permafrost 中使用

GPL-3.0 许可证

42KB
740

Permafrost

此crate提供了一个过程宏,用于将数据嵌入到你的Rust代码中。

示例

use permafrost::embed;

/// Expands to a const item that contains a greeting.
macro_rules! greet {
    (
        $who:literal
    ) => {
        embed! {
            #[allow(dead_code)]
            const [< HELLO _ $who:case{upper} >]:concatenate : &str = [< "Hello" " " $who "!" >]:concatenate{string};
        }
    }
}

greet!("Jonas");
// Recursive expansion of greet! macro
// ====================================

const HELLO_JONAS: &str = r#"Hello Jonas!"#;

使用方法

将以下内容添加到你的 Cargo.toml

permafrost = "1"

背景

这最初是一个用于替换 paste crate 的替代品,该crate允许你连接标识符并对它们应用大小写转换。

但是看到 paste crate 已经不再定期更新,而且我需要用于kebab case的大小写转换,我决定创建一个更强大和灵活的替代品。

结构

所有内容都传递给 embed 宏,这是底层引擎的入口点。!!! 初始时,只传递一个 token tree 作为任意 transformer chain 的顶级转换器,然后通过 token stream 进行纯计算。

块是 embed 宏的主要构建块,因为它们表示一个具有转换能力的 token stream

块由方括号定义,用 < > 注释,因此,[< (..) >] 表示一个块,其中 (..) 是目标 token stream。块也可以有自己的转换器链,它将跟在块后面。

块语法用EBNF给出

token-stream = token-tree | segment;

token-tree = group | ident | literal | punct | ...;

segment = block transformer-chain;

transformer = ident | ident "{" token-stream "}";

transformer-chain = ":" transformer { "," transformer };

block = "[" "<" token-stream { token-stream } ">" "]" [ transformer-chain ];

转换器

所有当前可用的转换器如下

转换器 描述 参数 示例
concatenate 连接目标 token stream identstringr#ident [< (hello[world]):concatenate{ident} >]
ungroup 取消分组目标 标记流 [< (hello[world]):ungroup>]
展平 展平目标 标记流 [< (hello[world]):展平>]
反转 反转目标 标记流 [< (hello[world]):反转>]
转换为字符串 将目标 标记流 转换为字符串 [< (hello[world]):转换为字符串>]
取消转换为字符串 将目标 标记流 取消转换为字符串 [< "hello world":取消转换为字符串>]
情况 将目标 标记流 转换为特定情况 kebabsnakecamelpascalupperlowertitle [< (hello[world]):情况{pascal} >]
计数 计算目标 标记流 中的元素数量 [< (hello[world]):计数>]
追加 将目标 标记流 追加到另一个 标记流 [< (hello[world]):追加{[!]} >]
前缀 在目标 标记流 前添加另一个 标记流 [< (hello[world]):前缀{[!]} >]

如果您认为缺少了一个基本的转换器,请提交一个问题。

依赖项

~1.2–1.8MB
~34K SLoC