在 Rust 中,我怎样才能得到 handlebars_helper!处理 JSON 对象

In Rust, how can I get handlebars_helper! to handle a JSON object

希望这个问题的上下文足够...

将 Handlebars 与 Rust 结合使用,我正在尝试实现一个处理程序来处理此输入:

 {{toJSON JSON_OBJ_OR_NONE}}

其中 JSON_OBJ_OR_NONE 是 JSON 的有效片段,如

{
   "abc": 123,
   "def": ["g", "h", "i"],
   "jkl": {
     "m": 1,
     "n": "op"
   }
}

或什么都没有(空字符串)。

它应该 return 是提供的 JSON 的漂亮印刷版本,或者如果 JSON_OBJ_OR_NONE 为空则为“{}”。

所提供的JSON片段完全是任意的;它可以包含任何有效的 JSON 或空字符串。输出应该漂亮。

我已经尝试通过多种不同的方式来实现它,我目前处于

handlebars_helper!(toJSON: |json_obj_or_none: str|
if json_obj_or_none.is_empty() {
    "{}"
} else {
    let s = serde_json::to_string_pretty(&json_obj_or_none).is_ok().to_string();
    &s[..]
});

这看起来很接近,但我看到了

error[E0597]: `s` does not live long enough
   --> src/main.rs:145:10
    |
145 |         &s[..]
    |         -^----
    |         ||
    |         |borrowed value does not live long enough
    |         borrow later used here
146 |     });
    |     - `s` dropped here while still borrowed

编译的时候

虽然这似乎接近可行的解决方案,但我怀疑还有更优雅的编码方式。

代码如下:

{
   let s = something;
   &s
}

在 Rust 中几乎总是一个错误。引用总是借用某个东西,而那个东西被销毁后引用就不存在了。局部变量在其作用域结束时被销毁。

所以这意味着:

  1. 制作s
  2. 借自s
  3. 销毁s及其内容
  4. Return 对刚刚被销毁的那个东西的引用

因此您需要传递所有权:

{
   let s = something;
   s // not borrowed!
}

或通过将 let 移动到更高级别的范围来确保 s 不会很快被破坏:

let s;
{
   s = something;
   &s
   // `s` isn't destroyed here, because `let s` was outside `{}`
}
// `s` and `&s` are destroyed now

如果你将它与 if/else 中的字符串文字混合,Rust 会抱怨 String&str 不同。使用 String::from("") 作为文字,或查看包含两者的 Cow 类型。 Rust 需要知道哪些字符串要释放(String),哪些不能释放(&str),这就是为什么有两种类型。

总结一下,我最终让它按如下方式工作:

handlebars_helper!(toJSON: |json_obj_or_none: object|
if json_obj_or_none.is_empty() {
    "{}".into()
} else {
    let s = serde_json::to_string_pretty(&json_obj_or_none).unwrap_or_else(|_| "{}".to_string());
    s
});