6 个版本 (破坏性更新)
0.5.0 | 2021年10月24日 |
---|---|
0.4.0 | 2020年12月30日 |
0.3.0 | 2020年12月14日 |
0.2.0 | 2020年5月25日 |
0.1.1 | 2020年1月9日 |
#394 in 编码
5,223 monthly downloads
在 3 个crate中使用(直接使用2个)
105KB
2K SLoC
Proteus —
这个库旨在通过 serde 序列化,使用 JSON 反序列化,以及类似于 JavaScript JSON 语法的 JSON 转换语法,使数据的动态转换变得简单。它还支持注册自定义动作以用于语法。
[dependencies]
proteus = "0.1"
获取器/设置器语法
获取器和设置器语法是定制的,以支持自定义/动态动作,并且与设置器具有额外的选项几乎相同。如果需要其他解析语法,则可以使用它以与内部相同的方式构建转换。
转换语法与在 JavaScript 中访问 JSON 数据非常相似。要处理特殊字符,例如空白(空格)、方括号、引号和点,可以使用显式键语法 ["example[].blah""]
,它将代表以下 JSON 中的键
{
"example[].blah" : "my value"
}
重要:操作顺序很重要。
获取器
语法 | 描述 |
---|---|
这将获取顶层值,它可以是任何有效的类型:对象、数组、... | |
id | 获取 JSON 对象的名称。例如,HashMap 中的键 |
[0] | 获取指定索引处的 JSON 数组索引。 |
profile.first_name | 使用点表示法组合对象名称。 |
profile.address[0].street | 还支持使用点表示法和索引的组合。 |
设置器
语法 | 描述 |
---|---|
这将设置目标中的顶层值 | |
id | 本身任何文本都被视为 JSON 对象的名称。 |
[] | 此操作将源 数据 添加到数组中,如果它不存在则创建它,并且仅在 set 语法末尾有效,例如 profile.address[] |
[+] | 源数组应将其所有值追加到目标数组中,并且仅在 set 语法末尾有效,例如 profile.address[] |
[-] | 源数组值应替换目标数组中重叠索引处的值,并且仅在 set 语法末尾有效,例如 profile.address[] |
{} | 此操作将提供的对象合并到现有对象之上,并且仅在 set 语法末尾有效,例如 profile{} |
profile.first_name | 使用点表示法组合对象名称。 |
profile.address[0].street | 还支持使用点表示法和索引的组合。 |
示例用法
use proteus::{actions, TransformBuilder};
use std::error::Error;
// This example show the basic usage of transformations
fn main() -> Result<(), Box<dyn Error>> {
let input = r#"
{
"user_id":"111",
"first_name":"Dean",
"last_name":"Karn",
"addresses": [
{ "street":"26 Here Blvd", "postal":"123456", "country":"Canada", "primary":true },
{ "street":"26 Lakeside Cottage Lane.", "postal":"654321", "country":"Canada" }
],
"nested": {
"inner":{
"key":"value"
},
"my_arr":[null,"arr_value",null]
}
}"#;
let trans = TransformBuilder::default()
.add_actions(actions!(
("user_id", "id"),
(
r#"join(" ", const("Mr."), first_name, last_name)"#,
"full-name"
),
(
r#"join(", ", addresses[0].street, addresses[0].postal, addresses[0].country)"#,
"address"
),
("nested.inner.key", "prev_nested"),
("nested.my_arr", "my_arr"),
(r#"const("arr_value_2")"#, "my_arr[]")
)?)
.build()?;
let res = trans.apply_from_str(input)?;
println!("{}", serde_json::to_string_pretty(&res)?);
Ok(())
}
或者当你想进行结构到结构的转换时
use proteus::{actions, TransformBuilder};
use serde::{Deserialize, Serialize};
use std::error::Error;
#[derive(Serialize)]
struct KV {
pub key: String,
}
#[derive(Serialize)]
struct Nested {
pub inner: KV,
pub my_arr: Vec<Option<String>>,
}
#[derive(Serialize)]
struct Address {
pub street: String,
pub postal: String,
pub country: String,
}
#[derive(Serialize)]
struct RawUserInfo {
pub user_id: String,
pub first_name: String,
pub last_name: String,
pub addresses: Vec<Address>,
pub nested: Nested,
}
#[derive(Serialize, Deserialize)]
struct User {
pub id: String,
#[serde(rename = "full-name")]
pub full_name: String,
pub address: String,
pub prev_nested: String,
pub my_arr: Vec<Option<String>>,
}
// This example show the basic usage of transformations
fn main() -> Result<(), Box<dyn Error>> {
let input = RawUserInfo {
user_id: "111".to_string(),
first_name: "Dean".to_string(),
last_name: "Karn".to_string(),
addresses: vec![
Address {
street: "26 Here Blvd".to_string(),
postal: "123456".to_string(),
country: "Canada".to_string(),
},
Address {
street: "26 Lakeside Cottage Lane.".to_string(),
postal: "654321".to_string(),
country: "Canada".to_string(),
},
],
nested: Nested {
inner: KV {
key: "value".to_string(),
},
my_arr: vec![None, Some("arr_value".to_owned()), None],
},
};
let trans = TransformBuilder::default()
.add_actions(actions!(
("user_id", "id"),
(
r#"join(" ", const("Mr."), first_name, last_name)"#,
"full-name"
),
(
r#"join(", ", addresses[0].street, addresses[0].postal, addresses[0].country)"#,
"address"
),
("nested.inner.key", "prev_nested"),
("nested.my_arr", "my_arr"),
(r#"const("arr_value_2")"#, "my_arr[]")
)?)
.build()?;
let res: User = trans.apply_to(input)?;
println!("{}", serde_json::to_string_pretty(&res)?);
Ok(())
}
操作
以下都是支持的操作。
action | 描述 |
---|---|
const("Mr.") | 用于定义一个常量值。 |
join(",", const("Mr."), first_name, last_name) | 使用提供的分隔符连接一个或多个值 |
len(array_field) | 返回字符串、数组或对象的长度(按键的数量计)。 |
strip_start("v", key) | 从字符串值中删除提供的前缀。 |
strip_end("v", key) | 从字符串值中删除提供的后缀。 |
sum(cost, taxes, const(1)) | 计算一个或多个提供的值之和。 |
trim(key) | 从字符串中去除开头和结尾的空白。 |
trim_start(key) | 从字符串中去除开头的空白。 |
trim_end(key) | 从字符串中去除结尾的空白。 |
许可证
根据您选择的许可证,在 Apache License, Version 2.0 或 MIT 许可证下授权。Apache 许可证,版本 2.0 或 MIT 许可证除非您明确声明,否则您提交给 Proteus 的任何贡献,根据 Apache-2.0 许可证定义,应按上述方式双重许可,而不附加任何额外条款或条件。
依赖项
~3–5MB
~93K SLoC