54 次重大发布
0.57.0 | 2024年4月25日 |
---|---|
0.55.0 | 2023年3月19日 |
0.54.0 | 2023年3月19日 |
0.53.0 | 2022年5月9日 |
0.7.0 | 2020年11月29日 |
#32 in 编程语言
3,216 次每月下载
用于 2 crates
255KB
8K SLoC
节点仓库
为 lib-ruby-parser
仓库共享构建脚本和元数据。
文档
基本 API
节点
AST 节点信息通过 Node
/NodeField
/NodeFieldType
类型表示,您可以调用 nodes
函数检索所有节点。每个已知的节点都有一个名称和字段列表(两者都有注释作为数据)
use lib_ruby_parser_nodes::{nodes, Node, NodeField, NodeFieldType};
let all_nodes = nodes();
assert_eq!(nodes().len(), 124);
let def_node: &Node = all_nodes
.iter()
.find(|node| node.camelcase_name == "Def")
.unwrap();
assert_eq!(def_node.fields.len(), 8);
let expression_l_field: &NodeField = def_node
.fields
.iter()
.find(|field| field.snakecase_name == "expression_l")
.unwrap();
assert_eq!(expression_l_field.field_type, NodeFieldType::Loc);
消息
消息具有相同的 API,但使用 Message
/MessageField
/MessageFieldType
类型
use lib_ruby_parser_nodes::{messages, Message, MessageField, MessageFieldType};
let all_messages = messages();
assert_eq!(messages().len(), 90);
let nth_ref_is_too_big_message: &Message = all_messages
.iter().find(|message| message.camelcase_name == "NthRefIsTooBig").unwrap();
assert_eq!(nth_ref_is_too_big_message.fields.len(), 1);
let nth_ref_field: &MessageField = nth_ref_is_too_big_message
.fields
.iter()
.find(|field| field.snakecase_name == "nth_ref")
.unwrap();
assert_eq!(nth_ref_field.field_type, MessageFieldType::Str);
模板支持
此仓库主要用于其他仓库中的代码生成。有超过 100 个节点和 100 条消息,因此代码生成是处理它们的最佳方式。
Liquid 被用作主要的模板语言
use lib_ruby_parser_nodes::LiquidTemplate;
let template = LiquidTemplate::new_eval("
Nodes count: {{ nodes.size }}
Messages count: {{ messages.size }}
");
// Or LiquidTemplate::new("path/to/file.liquid")
assert_eq!(
template.render().trim(),
"Nodes count: 124\nMessages count: 90"
);
默认情况下,以下全局变量可用
nodes
- 设置为lib_ruby_parser_nodes::nodes()
messages
- 设置为lib_ruby_parser_nodes::messages()
可以在模板上调用 .with_global
来注册其他数据
use lib_ruby_parser_nodes::{
LiquidTemplate,
reexports::liquid::value,
};
let output = LiquidTemplate::new_eval("{{ custom_global }} bar")
.with_global("custom_global", value!("foo"))
.render();
assert_eq!(output, "foo bar")
默认情况下,以下过滤器可用
- 所有默认 liquid 过滤器
| camelcase_to_snakecase
- 将FooBar
字符串转换为foo_bar
| snakecase_to_camelcase
- 将foo_bar
字符串转换为FooBar
| escape_c_keyword
- 如果字符串是 C 关键字,则将其附加_
| escape_cpp_keyword
- 如果字符串是C++关键字,则将其附加到字符串中的_
| escape_rust_keyword
- 如果字符串是Rust关键字,则将其附加到字符串中的_
| escape_js_keyword
- 如果字符串是JavaScript关键字,则将其附加到字符串中的_
| render_comment: "//", 4
- 将字符串数组(如node.comment
)渲染为字符串,其中每行前缀为 "//",并填充4个空格(除第一行外,第一行没有填充)
可以通过在模板上调用 .with_filter
来注册自定义过滤器
use liquid_core::{
Result, Runtime, Value, ValueView,
Display_filter, Filter, FilterReflection, ParseFilter,
};
#[derive(Clone, ParseFilter, FilterReflection)]
#[filter(
name = "append_foo",
description = "Appends 'foo' to a given string.",
parsed(AppendFooFilter)
)]
pub struct AppendFoo;
#[derive(Debug, Default, Display_filter)]
#[name = "append_foo"]
struct AppendFooFilter;
impl Filter for AppendFooFilter {
fn evaluate(&self, input: &dyn ValueView, _runtime: &dyn Runtime) -> Result<Value> {
let input = input.to_kstr();
let output = format!("{}foo", input);
Ok(Value::scalar(output))
}
}
use lib_ruby_parser_nodes::LiquidTemplate;
let template = LiquidTemplate::new_eval("{{ 'data ' | append_foo }}")
.with_filter(AppendFoo)
.render();
assert_eq!(template, "data foo");
您还可以查看更复杂的过滤器(如 render_comment
),以了解如何传递参数。
将代码生成脚本发布到 wasmer.io
- 在
wasmer.toml
中更新版本 cargo构建 --示例代码生成 --发布 --目标wasm32-wasi
wasmer publish
发布后,可以使用以下方式执行
$ wasmer run \
--mapdir /pwd:. \
iliabylich/lib-ruby-parser-nodes -- \
--template /pwd/template.liquid \
--write-to /pwd/output.ext
依赖项
~6–8MB
~152K SLoC