![](/img/trans.png)
[英]Serde Stream Deserializer for a type other than serde_json::Value
[英]Convert serde_json Value keys to camelCase
我正在编写一个读取 JSON 文件的 CLI 工具,应该将 JSON object 键转换为驼峰命名法。
因为这应该适用于任何 JSON 文件,所以我显然不能只使用强类型然后使用#[serde(rename_all = "camelCase")]
。
我似乎无法在serde_json
中找到一种明显的方法来使其使用serde
显然已经存在的重命名代码并将其应用于serde_json::value::Value
。
我错过了一些明显的东西吗?
您必须编写一个 function 递归通过serde_json::Value
结构并在遇到一个时替换serde_json::Map
的键。 这实现起来有点尴尬,因为没有Map::drain
。
fn rename_keys(json: &mut serde_json::Value) {
match json {
serde_json::Value::Array(a) => a.iter_mut().for_each(rename_keys),
serde_json::Value::Object(o) => {
let mut replace = serde_json::Map::with_capacity(o.len());
o.retain(|k, v| {
rename_keys(v);
replace.insert(
heck::ToLowerCamelCase::to_lower_camel_case(k.as_str()),
std::mem::replace(v, serde_json::Value::Null),
);
true
});
*o = replace;
}
_ => (),
}
}
use std::io::Read;
fn main() {
let mut stdin = vec![];
std::io::stdin()
.read_to_end(&mut stdin)
.expect("Read stdin");
let mut json = serde_json::from_slice::<serde_json::Value>(&stdin).expect("Parse Json");
rename_keys(&mut json);
println!("{}", serde_json::to_string_pretty(&json).unwrap());
}
(请注意, rename_keys
会在深度 JSON 结构上产生堆栈溢出,但serde_json
默认情况下仅解析到有限的深度,因此无需担心。如果您确实需要支持深层嵌套结构,请查看serde_stacker
。)
如果您对serde_json::Value
本身不感兴趣,只想转换 JSON 字符串,那么还有两种方法可以转换为 go:
serde_json::Value
的包装器结构编写自定义序列化程序来对序列化进行重命名。 此处提供了此类序列化程序的示例,但您必须采用它才能递归。 (可能在反序列化时比在序列化时更容易)serde_json::Value
结构和对令牌 stream 的重命名(使用 GB 的 JSON 时无需担心)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.