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(()) } - The compilation fails if I uncomment the line with
to_string_pretty(&z), which is good. - Even without that line, the compilation fails on the
let _z = ...line if I uncommentwhere T: Serialize. This is great, because it helps the library integrators to spot they are usingstruct Xwith 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?