1

I'm trying to make a library that serializes things using serde but I'd like better type-safety. Specifically: the format is much more restrictive than serde and I'd like field types incompatible with my format to be rejected at compile-time. I'd also like to have a separate trait/derive macro for this. Is there a good example of this or something similar being done in a crate somewhere? What I'd want is something like this:

// Option, String, and Vec are OK
#[derive(Clone, Debug, MyRestrictedSerialize)]
#[skip_serializing_none]
pub struct ValidType {
    pub field: Option<String>,
    pub field2: Vec<String>,

// Compile-time error, i64 and bool are not allowed
#[derive(Clone, Debug, MyRestrictedSerialize)]
#[skip_serializing_none]
pub struct InvalidType {
    pub field: Option<i64>,
    pub field2: Vec<bool>,
    pub field3: i64,

I'm almost positive someone has done something like this before but perusing crates.io hasn't led to anything that quite fits what I'm thinking of. I'm considering writing a macro that implements a wrapper trait that is requires Serialize if-and-only-if the type is valid for the intended format but that seems a little icky. Something like this:

trait MyRestrictedSerialize<T: Serialize = Self> {
  fn my_serialize(…) -> MyFormat {
    …
  }
}

First: am I on the right track? Is there another approach I should consider?

Second: Are there any crates solving a similar problem? I can't be the first person implementing a format that can only express a subset of what serde allows who wants to reject invalid types at compile-time.

Indoood
  • 11
  • 1

0 Answers0