6个版本
0.2.1 | 2022年5月25日 |
---|---|
0.2.0 | 2022年3月19日 |
0.1.3 | 2021年5月7日 |
0.1.2 | 2021年4月13日 |
在过程宏中排名第1699
每月下载量16,697次
在 3 crate中使用
19KB
141 行
display_json
Rust标准库提供了一些特质,允许你的类型实现,以便将它们序列化(std::fmt::{Display, Debug}
)或反序列化(std::str::FromStr
)为字符串。在Rust中,数据类型的序列化和反序列化通常通过实现serde crate中的Serialize
和Deserialize
特质来完成。display_json
是一个crate,它允许你通过自定义派生过程宏轻松地将serde
的功能与这些来自std
的特质集成。这些宏通过将serde_json的序列化和反序列化能力封装进std
的特质中来将你的类型序列化和反序列化为json字符串。
目录
使用Rust std的fmt特质将对象序列化为json
display_json
为您提供了一种简单的方法,将对象的序列化与 Rust 内置的格式化功能(由 Display
和 Debug
特性提供)相结合。对于字符串序列化为 JSON,display_json
暴露了自定义 derive 程序性宏 DisplayAsJson
、DisplayAsJsonPretty
、DebugAsJson
和 DebugAsJsonPretty
。这使得您可以使用 std
。这些自定义 derive 创建了对象的字符串化 JSON 版本,使用 serde_json。这四个自定义 derive 宏基本上是整洁的包装器,将 serde_json 包中的 to_string
和 to_string_pretty
函数包装成一个实现了 Display
或 Debug
的类型。
DisplayAsJson
没有 display_json
,您必须像这样将对象序列化为 JSON 字符串
use serde::Serialize;
use serde_json::{Result, to_string};
#[derive(Serialize)]
struct Foo {
bar: String,
baz: i32,
bat: bool,
}
fn main() -> Result<()> {
let f = Foo { bar: "bar".to_owned(), baz: 0, bat: true };
let s = to_string(&f)?;
assert_eq!(s, r#"{"bar":"bar","baz":0,"bat":true}"#);
Ok(())
}
使用 Foo
上的 DisplayAsJson
自定义 derive,可以更少的代码完成相同的工作
use serde::Serialize;
use display_json::DisplayAsJson;
#[derive(Serialize, DisplayAsJson)]
struct Foo {
bar: String,
baz: i32,
bat: bool,
}
let f = Foo { bar: "bar".to_owned(), baz: 0, bat: true };
assert_eq!(f.to_string(), r#"{"bar":"bar","baz":0,"bat":true}"#);
DisplayAsJson
是 serde_json::to_string
的包装器。它接收序列化的 JSON 字符串,并将其提供给由 DisplayAsJson
实现的 Display
特性。这使得将对象格式化为 JSON 更加方便。例如,您可以使用此方法创建易于消费的日志消息或序列化数据以发送作为 HTTP 请求的主体
use serde::Serialize;
use display_json::DisplayAsJson;
#[derive(Serialize, DisplayAsJson)]
struct Foo {
bar: String,
baz: i32,
bat: bool,
}
let f = Foo { bar: "bar".to_owned(), baz: 0, bat: true };
// log `f` to stdout:
println!("{}", f);
// or you could construct an http request body from it
// or process your serialized object any other way you please
DebugAsJson
DebugAsJson
与 DisplayAsJson
工作方式相同,只是它不是实现 Display
特性,而是实现 Debug
特性
use serde::Serialize;
use display_json::DebugAsJson;
#[derive(Serialize, DebugAsJson)]
struct Foo {
bar: String,
baz: i32,
bat: bool,
}
let f = Foo { bar: "bar".to_owned(), baz: 0, bat: true };
// note that we use the debug formatter for serializing `f` to json
let f_ser = format!("{:?}", f);
assert_eq!(f_ser, r#"{"bar":"bar","baz":0,"bat":true}"#);
漂亮的json
DisplayAsJsonPretty
和 DebugAsJsonPretty
与它们的不美观版本工作方式相同,只是生成多行、缩进的 JSON 字符串而不是紧凑的 JSON 字符串
use serde::Serialize;
use display_json::{DisplayAsJsonPretty, DebugAsJsonPretty};
#[derive(Serialize, DisplayAsJsonPretty, DebugAsJsonPretty)]
struct Foo {
bar: String,
baz: i32,
bat: bool,
}
let f = Foo { bar: "bar".to_owned(), baz: 0, bat: true };
let result = r#"{
"bar": "bar",
"baz": 0,
"bat": true
}"#;
let f_ser = format!("{}", f);
let f_ser_dbg = format!("{:?}", f);
assert_eq!(f_ser, f_ser_dbg);
assert_eq!(f_ser, result);
assert_eq!(f_ser_dbg, result);
混合Display和Debug
如您在上述示例中看到的那样,您可以根据喜好组合 DisplayAsJson
和 DebugAsJson
变体。例如,您可以使用 DisplayAsJson
序列化对象以作为 HTTP 请求的主体,并使用 DebugAsJsonPretty
创建易于阅读的调试消息以调试您的代码。
使用Rust std的FromStr特质从json反序列化对象
虽然通常通过直接将程序与 serde 和 serde_json 包集成来执行 JSON 字符串的反序列化,但有时您想或必须使用 Rust 标准库的 trait std::str::FromStr
,这是 std
中类型执行字符串反序列化的方式。这可能是由于与其他执行字符串反序列化的包的互操作性限制,而不需要 serde
集成。这样的包的一个例子是 clap 的 derive api。
如果您发现自己面临着需要实现 std::str::FromStr
的事实,尽管它实现了 serde::Deserialize
,而且您没有打算想出一个带有解析器的自定义格式,以手动编写 FromStr
的实现,那么 display_json
是一个很好的选择。
FromStrAsJson
display_json
公开了FromStrAsJson
自定义派生过程宏,您可以在您的类型上使用它。 FromStrAsJson
通过包装std::str::FromStr
实现了serde_json::from_str
。如果您需要为您的类型实现FromStr
特性和您所做的一切只是使用它来反序列化JSON字符串,那么FromStrAsJson
就是您的解决方案,以最少的代码量确保您的注意力集中在您的程序要做什么,而无需您盯着样板代码。
FromStrAsJson
的使用方法如下
use serde::Deserialize;
use display_json::FromStrAsJson;
use std::str::FromStr;
#[derive(Deserialize, FromStrAsJson, PartialEq, Debug)]
struct Foo {
bar: String,
baz: i32,
bat: bool,
}
let f_as_json = r#"{"bar":"bar","baz":0,"bat":true}"#;
let f = Foo { bar: "bar".to_owned(), baz: 0, bat: true };
assert_eq!(Foo::from_str(f_as_json).unwrap(), f);
依赖项
~1.5–2MB
~49K SLoC