实现 DeserializeOwned 的通用类型
Generic type that implements DeserializeOwned
下面是一个无法运行的代码示例:
use serde_json::json;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Model<T>
where
T: DeserializeOwned,
{
pub id: i32,
pub info: Option<T>,
}
fn main() {
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Info {
name: String,
}
let some_model_1: Model<Info> = serde_json::from_value(json!({
"id": 43,
"info": {
"name": "some_model_name"
}
}))
.unwrap();
println!("some_model_1: {:#?}", some_model_1);
let some_model_2: Model<Info> = serde_json::from_value(json!({
"id": 43
}))
.unwrap();
println!("some_model_2: {:#?}", some_model_2);
}
错误如下:cannot satisfy 'T: Deserialize<'de>
.
所以我添加了:
#[serde(deserialize_with = "Option::deserialize")]
pub info: Option<T>,
现在代码可以编译,但是 some_model_2
缺少的“信息”对象导致错误,尽管使用了选项类型:
thread 'main' panicked at 'called 'Result::unwrap()' on an 'Err' value: Error("missing field 'info'", line: 0, column: 0)', src\main.rs:34:6
我最后的解决方案是使用自定义函数对 info
字段进行反序列化:
use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
use serde_json::{json, Value};
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Model<T>
where
T: DeserializeOwned,
{
pub id: i32,
#[serde(deserialize_with = "ok_or_none")]
pub info: Option<T>,
}
fn ok_or_none<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de>,
{
let v = Value::deserialize(deserializer)?;
Ok(T::deserialize(v).ok())
}
fn main() {
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Info {
name: String,
}
let some_model_1: Model<Info> = serde_json::from_value(json!({
"id": 43,
"info": {
"name": "some_model_name"
}
}))
.unwrap();
println!("some_model_1: {:#?}", some_model_1);
let some_model_2: Model<Info> = serde_json::from_value(json!({
"id": 43
}))
.unwrap();
println!("some_model_2: {:#?}", some_model_2);
}
此更改无济于事,同样的恐慌错误仍然存在。 ok_or_none
函数甚至没有被调用。
以下是我的依赖项:
serde = { version = "1.0.94", features = ["derive"] }
serde_json = "1.0.40"
我不知道我还能做些什么来完成这项工作。
提前感谢您的帮助!
你不需要使用 DeserializeOwned
,一个简单的 T
就足够了,当从 serde 派生时它会检查你的属性是否可以是 serialized/deserialized:
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Model<T> {
pub id: i32,
pub info: Option<T>,
}
fn main() {
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Info {
name: String,
}
let some_model_1: Model<Info> = serde_json::from_value(json!({
"id": 43,
"info": {
"name": "some_model_name"
}
}))
.unwrap();
println!("some_model_1: {:#?}", some_model_1);
let some_model_2: Model<Info> = serde_json::from_value(json!({
"id": 43
}))
.unwrap();
println!("some_model_2: {:#?}", some_model_2);
}
下面是一个无法运行的代码示例:
use serde_json::json;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Model<T>
where
T: DeserializeOwned,
{
pub id: i32,
pub info: Option<T>,
}
fn main() {
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Info {
name: String,
}
let some_model_1: Model<Info> = serde_json::from_value(json!({
"id": 43,
"info": {
"name": "some_model_name"
}
}))
.unwrap();
println!("some_model_1: {:#?}", some_model_1);
let some_model_2: Model<Info> = serde_json::from_value(json!({
"id": 43
}))
.unwrap();
println!("some_model_2: {:#?}", some_model_2);
}
错误如下:cannot satisfy 'T: Deserialize<'de>
.
所以我添加了:
#[serde(deserialize_with = "Option::deserialize")]
pub info: Option<T>,
现在代码可以编译,但是 some_model_2
缺少的“信息”对象导致错误,尽管使用了选项类型:
thread 'main' panicked at 'called 'Result::unwrap()' on an 'Err' value: Error("missing field 'info'", line: 0, column: 0)', src\main.rs:34:6
我最后的解决方案是使用自定义函数对 info
字段进行反序列化:
use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
use serde_json::{json, Value};
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Model<T>
where
T: DeserializeOwned,
{
pub id: i32,
#[serde(deserialize_with = "ok_or_none")]
pub info: Option<T>,
}
fn ok_or_none<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de>,
{
let v = Value::deserialize(deserializer)?;
Ok(T::deserialize(v).ok())
}
fn main() {
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Info {
name: String,
}
let some_model_1: Model<Info> = serde_json::from_value(json!({
"id": 43,
"info": {
"name": "some_model_name"
}
}))
.unwrap();
println!("some_model_1: {:#?}", some_model_1);
let some_model_2: Model<Info> = serde_json::from_value(json!({
"id": 43
}))
.unwrap();
println!("some_model_2: {:#?}", some_model_2);
}
此更改无济于事,同样的恐慌错误仍然存在。 ok_or_none
函数甚至没有被调用。
以下是我的依赖项:
serde = { version = "1.0.94", features = ["derive"] }
serde_json = "1.0.40"
我不知道我还能做些什么来完成这项工作。
提前感谢您的帮助!
你不需要使用 DeserializeOwned
,一个简单的 T
就足够了,当从 serde 派生时它会检查你的属性是否可以是 serialized/deserialized:
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Model<T> {
pub id: i32,
pub info: Option<T>,
}
fn main() {
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Info {
name: String,
}
let some_model_1: Model<Info> = serde_json::from_value(json!({
"id": 43,
"info": {
"name": "some_model_name"
}
}))
.unwrap();
println!("some_model_1: {:#?}", some_model_1);
let some_model_2: Model<Info> = serde_json::from_value(json!({
"id": 43
}))
.unwrap();
println!("some_model_2: {:#?}", some_model_2);
}