2个版本
新 0.1.1 | 2024年8月18日 |
---|---|
0.1.0 | 2024年8月18日 |
#1696 在 过程宏
150 每月下载量
在 permafrost 中使用
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 |
ident 、string 、r#ident |
[< (hello[world]):concatenate{ident} >] |
ungroup |
取消分组目标 标记流 |
[< (hello[world]):ungroup>] |
|
展平 |
展平目标 标记流 |
[< (hello[world]):展平>] |
|
反转 |
反转目标 标记流 |
[< (hello[world]):反转>] |
|
转换为字符串 |
将目标 标记流 转换为字符串 |
[< (hello[world]):转换为字符串>] |
|
取消转换为字符串 |
将目标 标记流 取消转换为字符串 |
[< "hello world":取消转换为字符串>] |
|
情况 |
将目标 标记流 转换为特定情况 |
kebab 、snake 、camel 、pascal 、upper 、lower 、title |
[< (hello[world]):情况{pascal} >] |
计数 |
计算目标 标记流 中的元素数量 |
[< (hello[world]):计数>] |
|
追加 |
将目标 标记流 追加到另一个 标记流 |
[< (hello[world]):追加{[!]} >] |
|
前缀 |
在目标 标记流 前添加另一个 标记流 |
[< (hello[world]):前缀{[!]} >] |
如果您认为缺少了一个基本的转换器,请提交一个问题。
依赖项
~1.2–1.8MB
~34K SLoC