You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Certain serialization formats require additional metadata about struct fields beyond their type and name to correctly serialize and deserialize data.
A prominent example is Google's Protocol Buffers (protobuf), where each field in a message is identified by a unique, pre-determined number called a field tag. Furthermore, protobuf supports different encoding options for fields, such as variable-length, fixed-size, or length-delimited encoding for integers and other data types.
Currently, the Serializer and Deserializer traits in Serde do not provide a mechanism to pass such additional metadata to the serialization/deserialization implementation. This limitation makes it challenging to implement serializers for formats like protobuf using Serde.
To illustrate this issue, consider the following modified example inspired by the prost crate documentation:
use prost::{Enumeration,Message};#[derive(Clone,PartialEq,Message)]structPerson{#[prost(string, tag = "1")]pubid:String,// NOTE: Skipping to less commonly occurring fields#[prost(string, tag = "16")]pubname:String,}
In this example, each field has an associated tag attribute that specifies its unique identifier in the protobuf message as per the protobuf message structure. When attempting to serialize or deserialize this struct using a Serde-based protobuf serializer/deserializer, there is no straightforward way to pass the tag information to the Serializer or Deserializer, as Serde's traits do not accommodate such metadata.
There are a few potential workarounds for this limitation, such as:
Phantom Fields: Introducing phantom fields that signal to the serializer, by their field names, that it should update its internal state.
Thread-local Storage: Using thread-local storage to hold the field names, which can be accessed by the serializer/deserializer. Although this approach is quite hacky, it does not alter how other deserializers see the types.
Const Generics and Specialization: Wrapping field types in #[repr(transparent)] structs with const generics, and implementing a trait that uses the min_specialization feature. This approach might look something like:
The trait would then only be specialized for the wrapper type.
However, all of these workarounds have downsides, aside from being somewhat hacky. The phantom fields and specialization approach, in particular, actually change how other serializers/deserializers see the types, which introduces additional complexity and potential issues.
Proposed Solution
We could introduce a new, non-required method in the Serializer and Deserializer traits to allow passing additional metadata about struct fields, without breaking backward compatibility.
The StructMetadata struct would hold the original metadata, along with a function that accepts a field name as a key and returns a &'static FieldMetadata struct. The FieldMetadata struct would then have a method that takes a static attribute key and a generic type implementing Deserialize, returning an Option<T>, where T is the expected type of the attribute.
This approach would allow serializers and deserializers to access field-level metadata without altering how existing Serde implementations operate.
Thank you for taking the time to read this proposal and for considering its potential impact on Serde's ecosystem.
The text was updated successfully, but these errors were encountered:
Problem Statement
Certain serialization formats require additional metadata about struct fields beyond their type and name to correctly serialize and deserialize data.
A prominent example is Google's Protocol Buffers (protobuf), where each field in a message is identified by a unique, pre-determined number called a field tag. Furthermore, protobuf supports different encoding options for fields, such as variable-length, fixed-size, or length-delimited encoding for integers and other data types.
Currently, the
Serializer
andDeserializer
traits in Serde do not provide a mechanism to pass such additional metadata to the serialization/deserialization implementation. This limitation makes it challenging to implement serializers for formats like protobuf using Serde.To illustrate this issue, consider the following modified example inspired by the
prost
crate documentation:In this example, each field has an associated
tag
attribute that specifies its unique identifier in the protobuf message as per the protobuf message structure. When attempting to serialize or deserialize this struct using a Serde-based protobuf serializer/deserializer, there is no straightforward way to pass the tag information to theSerializer
orDeserializer
, as Serde's traits do not accommodate such metadata.There are a few potential workarounds for this limitation, such as:
#[repr(transparent)]
structs with const generics, and implementing a trait that uses themin_specialization
feature. This approach might look something like:However, all of these workarounds have downsides, aside from being somewhat hacky. The phantom fields and specialization approach, in particular, actually change how other serializers/deserializers see the types, which introduces additional complexity and potential issues.
Proposed Solution
We could introduce a new, non-required method in the
Serializer
andDeserializer
traits to allow passing additional metadata about struct fields, without breaking backward compatibility.Here’s an example of how this could look:
The
StructMetadata
struct would hold the original metadata, along with a function that accepts a field name as a key and returns a&'static FieldMetadata
struct. TheFieldMetadata
struct would then have a method that takes astatic
attribute key and a generic type implementingDeserialize
, returning anOption<T>
, whereT
is the expected type of the attribute.This approach would allow serializers and deserializers to access field-level metadata without altering how existing Serde implementations operate.
Thank you for taking the time to read this proposal and for considering its potential impact on Serde's ecosystem.
The text was updated successfully, but these errors were encountered: