前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Rhai 脚本引擎的简单应用示例

Rhai 脚本引擎的简单应用示例

作者头像
niqin.com
发布2022-06-30 16:31:32
9610
发布2022-06-30 16:31:32
举报
文章被收录于专栏:Rust 生态与实践

上一篇文章中,简单介绍了 Rhai 脚本引擎的作用和功能,详见 Rhai - Rust 的嵌入式脚本引擎

本文我们从最简单的字符串应用入手,来看看 Rhai 脚本的编写是多么简单。主要从三个应用点入手:在 Rust 程序中调用嵌入的 Rhai 脚本;独立的 Rhai 脚本;web 开发方面,结合模板引擎,调用 Rhai 脚本,进行模板的渲染辅助。

  • 在 Rust 程序中调用嵌入的 Rhai 脚本

首先,我们要在 Cargo.toml 中增加依赖项:

代码语言:javascript
复制
[dependencies]
rhai = "0.19.10"

然后,在 Rust 代码中,我们就可以对嵌入的 Rhai 脚本进行计算。示例是对字符串中的数字进行计算

代码语言:javascript
复制
use rhai::{Engine, EvalAltResult, INT};

fn main() -> Result<(), Box<EvalAltResult>> {
    let engine = Engine::new();

    let result = engine.eval::<INT>("40 + 2")?;

    println!("计算结果:{}", result); // 将会打印 42

    Ok(())
}

计算结果可以传递给其它 Rust 代码、Rhai 脚本,以及其它 Python 脚本、web 前端等,和 Rust 代码的写法基本相同。

  • 独立的 Rhai 脚本

下面的示例是纯粹的 Rhai 脚本示例,也是字符串处理,请注意 Rhai 作为 no-std 的 Rust 脚本引擎,引入了具有动态类型,因此写法是和 Rust 代码很相似,但更为容易:易写、易读。

代码语言:javascript
复制
// 本脚本测试字符串操作

print("您好!");                // 注意 Rust 代码中,使用宏 print! 或 println!
print("这样\n非常 \\ 棒!");     // 嵌入换行符
print("40 16 进制为:\x40");     // 转换为 16 进制
print("unicode:\u2764");       // Unicode
print("unicode:\U0001F603");   // Unicode
print("成都" + "->" + "三亚");     // 使用字符串构建字符串
print("foo" < "bar");           // 字符串比较,Rhai 中仅支持 ==、<、> 等
print("您" >= "你");          // 字符串比较,Rhai 中不支持 eq、lt、gt 等
print("输出结果为:" + 42);   // 使用非字符串类型的字符串构建

let s = "\u2764 hello, world! \U0001F603"; // 字符串变量
print("长度=" + s.len);       // 结果打印为 17

s[s.len-3] = '?';               // 修改字符串
print("修改结果为:" + s);        // 将打印 '修改结果为:hello, world?'
  • 结合模板引擎,调用 Rhai 脚本,进行模板的渲染辅助

下面的示例为在支持 Rhai 脚本解析(即模板依赖 crate 包含 Rhai)的模板引擎中,使用独立的 Rhai 脚本进行渲染辅助。

首先,在对模板的响应 handler 中,我们需要注册脚本助手,可以注册多个。如下实例我们注册 2 个,分别处理模板渲染时根据用户个人站点类别,展示对应的站点所属 svg,以及对用户博客名称进行处理:

代码语言:javascript
复制
pub async fn user_index(req: Request<State>) -> tide::Result {
    let mut user_tpl: Tpl = Tpl::new("users/index").await;
    user_tpl.reg.register_script_helper_file(
        "website-svg",
        format!("{}{}", rhai_dir().await, "website-svg.rhai"),
    )?;
    user_tpl.reg.register_script_helper_file(
        "blog-name",
        format!("{}{}", rhai_dir().await, "blog-name.rhai"),
    )?;
    ...
    ...

然后,独立的 Rhai 脚本 website-svg.rhai 为:

代码语言:javascript
复制
let website = params[0];
let is_github = website.contains("github.com");

if is_github {
    "M8 0C3.58 0 0 3.58 0 ..."
} else {
    "M6.5 14.5v-3.505c0-...."
}

脚本 blog-name.rhai 我们就省略了。

最后,在模板文件(即 html、jinja2、hbs 等)中,我们使用变量解析类似的方法进行调用:

代码语言:javascript
复制
<div class="col-4 text-center">
  <a class="blog-header-logo text-dark" href="{{ user.website }}" target="_blank">
    {{ blog-name user.blogName }}
    <svg width="28" height="28" viewBox="0 0 18 18" fill="currentColor">
      <path d="{{ website-svg user.website }}" />
    </svg>
  </a>
</div>

服务器端在对模板渲染时,模板引擎内置的 rhai 依赖 crate 将对 rahi 脚本进行计算。和文中第一个 rhai 应用途径——Rust 代码中嵌入 Rhai 脚本——类似。

通过三个途径的应用示例,我们可以发现:Rhai 总体应用范畴来说,目前还很狭小。并且除了性能特别出色这个优点外,其它优势并非特别明显。

体验者大多基于对 Rust 语言性能的信赖,从而作为将复杂问题简单化的以辅助。比如笔者目前的应用,也主要聚焦于模板渲染辅助方面。

对于特别看重性能的应用来说,Rhai 脚本引擎是个非常值得考虑的。其余考量点来说,技术栈也会多了一个选项。感兴趣的朋友可以访问网站:https://rhai.budshome.com,以作详细了解。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust 生态与实践 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档