Reputation: 2222
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.
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.let _z = ...
line if I uncomment where T: Serialize
. 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.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
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?
Upvotes: 4
Views: 1242
Reputation: 431489
You need to use #[serde(bound)]
to prevent Serde from attempting to automatically determine the bounds on the Deserialize
and Serialize
implementations:
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:
Upvotes: 9