Can I serialize a subset of fields and use a function to deserialize the other fields without manually implementing Serialize or Deserialize?

Viewed 427

I have the following struct

struct S {
    value: f32,
    square: f32,
}

I would like to derive square from value in the new(value):

impl S {
    fn new(value: f32) -> Self {
        Self { value, square: value.powi(2) }
    }
}

Can I use value field only to serialize the struct and use new(value) to deserialize the whole thing without manually implementing Serialize/Deserialize traits?

1 Answers

You can implement deserialization with the #[serde(from = "FromType")] attribute. If the transformation can fail, there is also the try_from attribute.

Deserialize this type by deserializing into FromType, then converting. This type must implement From<FromType>, and FromType must implement Deserialize.

Serializing a subset of fields can be achieved by applying the #[serde(skip)] annotation on the fields you want to omit.

Applied to your use case a solution looks like this:

#[derive(Debug, Serialize, Deserialize)]
#[serde(from = "DeserS")]
struct S {
    value: f32,
    #[serde(skip)]
    square: f32,
}

#[derive(Deserialize)]
struct DeserS {
    value: f32,
}

impl From<DeserS> for S {
    fn from(tmp: DeserS) -> Self {
        Self {
            value: tmp.value,
            square: tmp.value.powi(2),
        }
    }
}

Playground

Related