当为具有泛型类型参数的结构体派生 Serialize
和 Deserialize
实现时,大多数情况下 Serde 能够推断出正确的 trait 边界,无需程序员的帮助。它使用几种启发式方法来猜测正确的边界,但最重要的是,它会在每个序列化字段中包含的类型参数 T
上放置一个边界 T: Serialize
,并在每个反序列化字段中包含的类型参数 T
上放置一个边界 T: Deserialize
。就像大多数启发式方法一样,这并不总是正确的,Serde 提供了一个 escape
use serde::{de, Deserialize, Deserializer};
use std::fmt::Display;
use std::str::FromStr;
#[derive(Deserialize, Debug)]
struct Outer<'a, S, T: 'a + ?Sized> {
#[serde(deserialize_with = "deserialize_from_str")]
#[serde(bound(deserialize = "S: FromStr, S::Err: Display"))]
s: S,
#[serde(bound(deserialize = "Ptr<'a, T>: Deserialize<'de>"))]
ptr: Ptr<'a, T>,
}
fn deserialize_from_str<'de, S, D>(deserializer: D) -> Result<S, D::Error>
where
S: FromStr,
S::Err: Display,
D: Deserializer<'de>,
{
let s: String = Deserialize::deserialize(deserializer)?;
S::from_str(&s).map_err(de::Error::custom)
}
#[derive(Debug)]
enum Ptr<'a, T: 'a + ?Sized> {
#[allow(dead_code)]
Ref(&'a T),
Owned(Box<T>),
}
impl<'de, 'a, T: 'a + ?Sized> Deserialize<'de> for Ptr<'a, T>
where
Box<T>: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(Ptr::Owned)
}
}
fn main() {
let j = r#"
{
"s": "1234567890",
"ptr": "owned"
}
"#;
let result: Outer<u64, str> = serde_json::from_str(j).unwrap();
println!("result = {:?}", result);
}