serde icon indicating copy to clipboard operation
serde copied to clipboard

Implement `#[serde(implied(key = "key", value = "value")]` for adding static values

Open frectonz opened this issue 8 months ago • 3 comments

The implied Attribute

It would be useful to introduce an implied attribute in serde, which automatically adds a specific key-value pair during serialization and ensures that the key is present during deserialization. This would allow us to automatically include predefined keys (like method in the following example) in the serialized and deserialized data without manually specifying them in thestruct.

Example:

#[derive(Debug, Deserialize, Serialize)]
#[serde(implied(key = "method", value = "Target.setDiscoverTargets"))]
struct TargetSetDiscoverTargets {
    id: String,
    params: TargetSetDiscoverTargetsParams,
}
{
    "method": "Target.setDiscoverTargets",
    "id": "some-id",
    "params": {  }
}

Expected Behavior

1. Serialization

When serializing an instance of TargetSetDiscoverTargets, serde should automatically include the "method": "Target.setDiscoverTargets" key-value pair in the resulting JSON:

2. Deserialization

During deserialization, serde should check if the "method" key exists in the input and match it against the predefined value ("Target.setDiscoverTargets"). If it does not match or is missing, serde should raise an error.

Alternatives Considered

Manually adding the method field during serialization and validating its existence during deserialization. This approach introduces repetitive code that could be automated with the implied attribute. This also means that the user will have to implement Serialize and Deserialize themselves.

This PR implements this attribute.

frectonz avatar Mar 10 '25 04:03 frectonz

#1448 introduces #[serde(tag="...")] on structs. Your needs can be addressed with that code:

#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "method", rename = "Target.setDiscoverTargets")]
struct TargetSetDiscoverTargets {
    id: String,
    params: TargetSetDiscoverTargetsParams,
}

Is that would enough for you?

Mingun avatar Mar 10 '25 07:03 Mingun

Oh nice, #1448 handles the serialization part of the problem. It adds the tag key and value as a field when it serializes the struct, but it doesn't check for the tag when it deserializes.

frectonz avatar Mar 10 '25 07:03 frectonz

Hi everyone,

I hope you’re doing well! I wanted to follow up on my PR, which has been open for a couple of weeks without any progress. I’d appreciate any thoughts you might have on it and whether there’s anything I can do to facilitate the review process.

Please let me know if any changes or additional context are needed. Looking forward to your feedback!

Also, thank you for your work in serde ❤️ .

frectonz avatar Mar 24 '25 17:03 frectonz

At least for me it is counter-intuitive to use #[serde(tag = "method", rename = "Target.setDiscoverTargets")] and besides the lack of the validation during the deserialisation, it also does neither work with struct-like enum variants nor does it support adding multiple "constant" key-value pairs. Thus I would like to see this PR (or something alike) being merged.

ProbstDJakob avatar Jul 02 '25 14:07 ProbstDJakob