5个不稳定版本
0.12.0 | 2024年7月28日 |
---|---|
0.11.2 | 2023年8月14日 |
0.11.0 | 2023年7月18日 |
0.10.6 | 2023年5月17日 |
0.9.0 |
|
#20 在 过程宏 中排名
每月下载量50,829
用于 199 个crate(直接使用19个)
150KB
3K SLoC
rstml
在proc-macro::TokenStreams之上实现XML格式(HTML、SVG、MathML)的Rust模板。类似于JSX,但针对Rust(通常称为RSX)。解析结果是一个嵌套的Node结构,类似于浏览器的DOM,节点名称和值是syn表达式,以支持构建过程宏。
原始syn-rsx仓库的分支。由于各种原因创建了它
查看comparsion获取更多详细信息。
use std::convert::TryFrom;
use eyre::bail;
use quote::quote;
use rstml::{
node::{Node, NodeAttribute, NodeElement, NodeText},
parse2,
};
// Create HTML `TokenStream`.
let tokens = quote! { <hello world>"hi"</hello> };
// Parse the tokens into a tree of `Node`s.
let nodes = parse2(tokens)?;
// Extract some specific nodes from the tree.
let Node::Element(element) = &nodes[0] else {
bail!("element")
};
let NodeAttribute::Attribute(attribute) = &element.attributes()[0] else {
bail!("attribute")
};
let Node::Text(text) = &element.children[0] else {
bail!("text")
};
// Work with the nodes.
assert_eq!(element.name().to_string(), "hello");
assert_eq!(attribute.key.to_string(), "world");
assert_eq!(text.value_string(), "hi");
由 rstml 驱动
- html-to-string-macro - rstml 的基本使用示例,它使用
format!
宏将 HTML 转换为字符串。 - html-node -
html-to-string
宏的更强大版本,将 HTML 表示转换为 Rust 类型,这些类型可用于运行时内省。每种类型都具有Display
和Debug
实现因此可用于格式化打印 HTML 节点。 - leptos - 网络应用程序框架。在
view
/template
宏内部以及用于hot-reload
功能中使用了Rstml
。 - leptosfmt - 为
leptos
提供的 rustfmt 工具包装器,可以在view
宏内部格式化 HTML/XML 代码。 - sauron - 用于构建客户端和/或服务器端网络应用程序的通用网络框架和库。
功能
-
不具偏见
每个标签或属性名称都是有效的
<hello world />
-
文本节点
<div>"String literal"</div>
-
未引用的文本节点
未引用的文本支持有一些限制
- 仅有效的 Rust TokenStream 可以作为未引用的文本(不支持单引号文本,没有未闭合的大括号等)
- 未引用的文本并不总是可以节省空间。它使用
Span::source_text
和Span::join
来检索有关空格的信息,并且并不总是可用。 - 未引用文本附近的引用文本被视为不同的节点,因此库用户应决定何时保留引号。
<div> Some string that is valid rust token stream </div>
-
节点名称由破折号、冒号或双冒号分隔
<tag-name some:attribute-key="value" /> <tag::name attribute::key="value" />
-
具有保留关键字的节点名称
<input type="submit" />
-
文档类型、注释和片段
<!DOCTYPE html> <!-- "comment" --> <></>
-
大括号块被解析为任意 Rust 代码
<{ let block = "in node name position"; } /> <div>{ let block = "in node position"; }</div> <div { let block = "in attribute position"; } /> <div key={ let block = "in attribute value position"; } />
-
属性值可以是任何有效的 syn 表达式,无需要求大括号
<div key=some::value() />
-
开箱即用的错误报告功能
error: open tag has no corresponding close tag and is not self-closing --> examples/html-to-string-macro/tests/lib.rs:5:24 | 5 | html_to_string! { <div> }; | ^^^
-
能够获取整个节点的范围
这可以用于改进错误报告,例如。
error: Invalid element --> examples/src/main.rs:14:13 | 14 | / <div> 15 | | "invalid node for some consumer specific reason" 16 | | </div> | |__________________^
-
可恢复解析器
可以解析包含多个错误的 HTML。因此,库用户会得到一个错误数组,可以报告,并得到已解析的节点树。
<div hello={world.} /> <!-- dot after world is invalid syn expression --> <> <div>"1"</x> <!-- incorrect closed tag --> <div>"2"</div> <div>"3"</div> <div {"some-attribute-from-rust-block"}/> </>
使用此功能,可以以 IDE 友好的方式编写宏。此宏将更快地工作(因为在不合法的语法中,它稍微更改输出,而不是完全删除它,因此 IDE 可以快速检查差异)。并且更频繁地提供完成(转到定义和其他语义相关功能)。
-
自定义
一个
ParserConfig
可用于自定义解析行为,因此如果您对解析有稍微不同的要求并且尚未可自定义,请随时打开一个问题或拉取请求以扩展配置。关于自定义的一个亮点是
transform_block
配置,它接收一个闭包,该闭包接收原始块内容作为ParseStream
,并让您可以选择将其转换为TokenStream
。这使得在块中拥有自定义语法成为可能。更多详细信息请参阅 #9
依赖关系
~0.3–0.8MB
~19K SLoC