[英]Constraining generic parameter of Rust struct to be Deserialize
I would like to limit a (de)serializable struct to have a generic parameter that is also deserializable.我想限制(反)可序列化的结构具有一个也是可反序列化的泛型参数。 The derive macro
Deserialize
does not require me to add this constraint, which is nice, but I would like the integration code to get compilation errors even if they never try to deserialize the struct defined in the library.派生宏
Deserialize
不需要我添加这个约束,这很好,但我希望集成代码得到编译错误,即使它们从不尝试反序列化库中定义的结构。
use failure::Fallible; // 0.1.6
use serde::{Deserialize, Serialize}; // 1.0.104
use serde_json::to_string_pretty; // 1.0.44
#[derive(Deserialize, Serialize)]
struct X<T>
where
// T: Serialize,
{
a: u8,
t: T,
}
type Main<'a> = &'a dyn Fn() -> Fallible<()>;
fn main() -> Fallible<()> {
let x = X { a: 1, t: false };
println!("{}", to_string_pretty(&x)?);
let y: X<bool> = serde_json::from_str(r#"{"a":2,"t":true}"#)?;
println!("{}", y.t);
let _z: X<Main> = X { a: 3, t: &main };
// println!("{}", to_string_pretty(&z)?);
//let w: X<Main> = serde_json::from_str(r#"{"a":4,"t":NONONO}"#)?;
Ok(())
}
to_string_pretty(&z)
, which is good.to_string_pretty(&z)
取消注释该行,编译会失败,这很好。let _z = ...
line if I uncomment where T: Serialize
.where T: Serialize
,编译也会在let _z = ...
行上失败。 This is great, because it helps the library integrators to spot they are using struct X
with a non-serializable type parameter even before they actually start serializing it.struct X
I have tried to add where for<'a> T: serde::de::Deserialize<'a>
as a constraint to struct X<T>
, but that breaks the build even without anything using X
我试图添加
where for<'a> T: serde::de::Deserialize<'a>
作为对struct X<T>
的约束,但是即使没有使用X
任何东西也会破坏构建
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
struct X<T>
where
for<'a> T: serde::de::Deserialize<'a>,
{
a: u8,
t: T,
}
Is there a way to phrase this constraint I am looking for?有没有办法表达我正在寻找的这个约束?
You need to use #[serde(bound)]
to prevent Serde from attempting to automatically determine the bounds on the Deserialize
and Serialize
implementations:您需要使用
#[serde(bound)]
来防止 Serde 尝试自动确定Deserialize
和Serialize
实现的边界:
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
#[serde(bound = "T: Serialize, for<'de2> T: Deserialize<'de2>")]
struct X<T>
where
T: Serialize,
for<'de2> T: Deserialize<'de2>,
{
t: T,
}
struct NotSerializable;
fn main() {
X { t: true };
// X { t: NotSerializable }; // Generates compiler error
}
See also:也可以看看:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.