8个版本 (稳定版)
1.1.3 | 2024年1月1日 |
---|---|
1.1.2 | 2023年12月30日 |
0.1.0 | 2023年12月8日 |
#888在解析器实现
每月75次下载
在 5 crates中使用
53KB
1K SLoC
WJP - Wizards JSON解析器
一个库,可以将原始字符串解析为可操作的类型,反之亦然。
文档
基本用法
将库导入到Cargo.toml中
[dependencies]
wjp = "1.1.3"
// Example Struct to show how this library works
#[derive(Debug)]
struct Example {
code: f32,
messages: Vec<String>,
opt: Option<bool>,
}
// Implementing the Serialize Trait allows you to call the .json() method on your struct
impl Serialize for Example {
fn serialize(&self) -> Values {
// The map!() macro is a helper to create a hashmap from the given values
Values::Struct(map!(
// Many Data Structures and Types already have Serialize implemented
("code", self.code.serialize()),
("messages", self.messages.serialize()),
("opt", self.opt.serialize())
))
}
}
// Implementing the TryFrom<Values> Trait allows you to deserialize a JSON String into your struct
impl TryFrom<Values> for Example {
// We advise on using the ParseError because many helper methods build on this error
type Error = ParseError;
fn try_from(value: Values) -> Result<Self, Self::Error> {
// Now you just need to get your struct / array and get the keys with their appropriate values
let mut struc = value.get_struct().ok_or(ParseError::new())?;
let code = struc.map_val("code", f32::try_from)?;
// Many Data Structures and Types already have TryFrom<Values> implemented
let messages = struc.map_val("messages", Vec::try_from)?;
// This is sadly not the case for Option<T> where your need to find out what the type of T is and parse that
let opt = struc.map_opt_val("opt", |val| val.get_bool())?;
Ok(Self {
opt,
messages,
code,
})
}
}
pub fn main() {
let example = Example {
code: 123.0,
messages: vec!["Important".to_string(), "Message".to_string()],
opt: None,
};
// After implementing these two traits you can call the .json() method to serialize your struct
let json = example.json();
println!("{}", json);
// And the <Your Type>::deserialize(&str/String) to deserialize it
let back = Example::deserialize(json);
println!("{:?}", back);
}
上面示例的输出
{"opt":null,"code":123,"messages":["Important","Message"]}
Ok(Example { code: 123.0, messages: ["Important", "Message"], opt: None })
解释
JSON是一种轻量级、基于文本的、与语言无关的数据交换格式。尽管它是语言无关的,但它并不是针对Rust语言优化的。
示例JSON
{
"type": "error",
"message": "A really bad Error occurred",
"code": 444
}
键值对每次可能处于不同的位置
{
"code": 444,
"message": "A really bad Error occurred",
"type": "error"
}
这目前也是这个库的情况,因为它使用HashMap在新的位置分配键值对并从不同位置交付它们
键值对可能不存在、值为null或具有不同类型
{
"code": null,
"type": 123.23
}
这被支持,但会使解析部分更加困难,因此使用这个库的用户需要为它们想要解析的每个结构体实现From<Values>
和Serialize
JSON支持IEEE 754标准存储数字
{
"plus": 1,
"minus": -1,
"minus-zero": -0,
"exponent": 10E10,
"minus-exponent": 10e-10,
"decimal-point": 1.2,
"decimal-point-exponent": 1.23E-10
}
这被支持,但只是使用了f64::from_str()
,它应该支持所有这些情况
JSON也支持UTF-8编码
{
"text": "\u1234",
"info": " ^ This is not supported "
}
这个库不支持转义字符,并且不建议使用转义字符
JSON在数组内部也支持不同类型
[
true,
false,
null,
1.23,
false
]
这被支持,但用户需要弄清楚如何处理可以包含不同类型的Vec<Values>