如何从“.”生成 serde_json 对象分隔的文本格式?

How do I generate a serde_json object from a "." separated text format?

问题

我正在尝试通过解析如下所示的自定义宏格式来生成 json 对象(使用 serde):

Plot.Polar.max: 20
Plot.Polar.min: 0
Plot.Polar.numberlabel: 0101
Plot.Polar.chartname: small-chart
Plot.Polar.Var.1: 
Plot.Polar.Var.2: A label: with T+ES[T] #Data

我卡住的是如何为对象设置键。在我的旧 JavaScript 代码中,我拆分了 \n.:,有几个嵌套循环,最后有一个 reduceRight 来创建这样的对象:

// rowObject equals one row in the old macro format
let rowObject = keys.reduceRight(
  (allKeys, item) => ({ [item]: allKeys }),
  val,
);

我的目标

我的目标是使用那个 json 对象根据自定义宏中的键和值生成 highcharts 配置 (json)。我也希望能够仅以 json 格式打印宏,因此为什么我想先将宏转换为 json 而不是使用单独的数据结构(尽管这可能是个好主意? ).我想从宏中生成的 json 是这样的:

{
  "Plot": {
    "Polar": {
      "max": 20,
      "min": 0
    }
  }
}

我试过的

我的当前循环:

// pseudo
// let mut json_macro = new Map();
for row in macro_rows.iter() {
    let row_key_value: Vec<&str> = row.split(':').collect();
    let keys = row_key_value[0];
    let value = row_key_value[1];
    let keys_split: Vec<&str> = keys.split('.').collect();

    for key in keys_split.iter() {
        // TODO: accumulate a objects to row_object
    }
    // TODO: insert row_object to json_macro
}

问题

是否可以在 JavaScript 中执行类似 reduceRight 的操作或在 rust 中执行类似的操作?

更新

我意识到我必须将所有值都视为字符串,因为不可能知道数字是否是字符串。最终起作用的是@gizmo 提供的解决方案。

要将您的行插入 json_macro,您可以从左侧折叠 keys_split 并将每个键插入 top-level 对象:

let row_key_value: Vec<&str> = row.split(':').collect();
let keys = row_key_value[0];
let value: Value = serde_json::from_str(row_key_value[1]).unwrap();
let keys_split: Vec<&str> = keys.split('.').collect();
keys_split[..keys_split.len() - 1]
    .iter()
    .fold(&mut json_macro, |object, &key| {
        object
            .entry(key)
            .or_insert(Map::new().into())
            .as_object_mut()
            .unwrap()
    })
.insert(keys_split.last().unwrap().to_string(), value);

这里有一些关于 unwrap()s 的注意事项:

  • from_str(...).unwrap():我在这里将val解析为JSON对象。这可能不是您想要的。也许您想要 str::parse::<i32> 或其他东西。无论如何,此解析可能会失败。
  • .as_object_mut().unwrap():如果输入重新定义键,如
  • ,这将爆炸
Plot.Polar: 0
Plot.Polar.max: 20
  • 反过来,您可能希望处理键已定义为对象的情况。
  • keys_split.last().unwrap() 不会失败,但您可能想检查它是否为空字符串