#control-flow #rsx #html #syn #html-macro #jsx #macro

rstml-control-flow

为 rstml 实现控制流的自定义节点。当需要实现 If、For 等功能时很有用。

2 个版本

0.1.1 2024年7月28日
0.1.0 2024年7月28日

#218 in 过程宏

Download history 238/week @ 2024-07-28 2/week @ 2024-08-04

240 每月下载量

MIT 许可证

210KB
4.5K SLoC

rstml 的控制流实现

rstml 中用于控制流的 CustomNode 集合。

动机

此crate旨在提供一个如何使用自定义节点扩展 rstml 的示例。使用自定义节点而不是使用内部宏调用可以降低编写模板的复杂性,并允许 rstml 一次性解析整个模板。

自定义节点

rstml 中的自定义节点允许外部代码扩展 Node 枚举。这对于支持不常见于HTML/XML文档的定制语法很有用。它只能在 Node 的上下文中使用,不能在元素属性或节点名称中使用。

控制流实现

自定义节点的常见用例是实现 if/else 操作符和循环。此crate提供了两种不同的方式来实现 if/else 控制流。

使用标签的控制流

第一种方法是使用自定义标签。这是在HTML模板中实现控制流的最高效方式,因为控制流看起来像常规的HTML元素。这种方法的缺点是,无法在HTML元素属性中正确解析 Rust 表达式。例如,对于 <if foo > bar> </if>,很难确定属性标签的结束和内容的开始。

在这个包中,我们强制用户在标签的末尾使用一个特殊的分隔符。因此,而不是使用<if foo > bar> </if>,我们必须编写<if foo > bar !> </if>,其中!>是一个分隔符。这种特殊语法在<else if><for>标签内部也使用。

示例

use rstml::{parse2_with_config, node::*};
use rstml_controll_flow::tags::*;
use quote::quote;


let template = quote!{
<if foo !>
        <p> foo is true </p>
    <else if bar !>
        <p> bar is true </p>
    <else if/>
    <else>
        <p> foo and bar are false </p>
    <else/>
</if>
}

let nodes = parse2_with_config(template, Default::default().with_custom_nodes::<Conditions>())
.unwrap();

注意:标签else ifelse是可选的,并且它们的内容被移动到IfNode的字段中。标签if内的其他节点全部收集到IfNode::body字段中,即使它们在上面的示例中位于<else if/><else>标签之间。

使用转义符号在未引用文本中的控制流。

第二种方式是在未引用文本中使用转义符号。这种方法对于Rust来说更自然,因为它的声明方式与Rust代码相同。唯一的区别是{}内的块不是Rust代码,而是rstml模板。

示例

use rstml::{parse2_with_config, node::*};
use rstml_controll_flow::escape::*;
use quote::quote;


let template = quote!{
    <p>
        @if foo {
            <p> foo is true </p>
        } else if bar {
            <p> bar is true </p>
        } else {
            <p> foo and bar are false </p>
        }
    </p>
};

let nodes = parse2_with_config(template, Default::default().with_custom_nodes::<EscapedCode>())

EscapedCode转义字符是可配置的,默认使用“@”符号。

同时使用多个CustomNode

也可以同时使用多个CustomNode。例如,如果您想同时使用ConditionsEscapedCode自定义节点。rstml-control-flow包提供了一个ExtendableCustomNode结构体,可以将多个CustomNode组合成一个。请查看lib.rs中的extendable.rs文档和测试,以获取更多详细信息。

依赖关系

~0.3–0.8MB
~19K SLoC