-
Notifications
You must be signed in to change notification settings - Fork 7
Attribute macro to generate de/serialization functions for fields of big array type #17
Description
Like all of the standard library's traits, Serde's traits are limited to fixed size arrays up to an arbitrary maximum size. Serde defines Serialize and Deserialize impls for arrays up to size 32.
The current workaround for larger arrays in serde_big_array is workable but not ideal:
big_array! {
BigArray;
42, 300,
}
#[derive(Serialize, Deserialize)]
struct S {
#[serde(with = "BigArray")]
arr_a: [u8; 300],
#[serde(with = "BigArray")]
arr_b: [u8; 42],
arr_small: [u8; 8],
}It would be nicer to have an attribute macro that makes big arrays work by finding all fields of array type and inserting the appropriate serde(serialize_with = "...", deserialize_with = "...") functions (also generated by the attribute macro).
#[make_big_arrays_work]
#[derive(Serialize, Deserialize)]
struct S {
arr_a: [u8; 300],
arr_b: [u8; 42],
arr_small: [u8; 8],
}// generated code
#[derive(Serialize, Deserialize)]
struct S {
#[serde(
serialize_with = "big_array_serialize_S_arr_a",
deserialize_with = "big_array_deserialize_S_arr_a",
)]
arr_a: [u8; 300],
#[serde(
serialize_with = "big_array_serialize_S_arr_b",
deserialize_with = "big_array_deserialize_S_arr_b",
)]
arr_b: [u8; 42],
arr_small: [u8; 8],
}
fn big_array_serialize_S_arr_a<S>(
array: &[u8; 300],
serializer: S,
) -> core::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
/* ... */
}
fn big_array_deserialize_S_arr_a<'de, D>(
deserializer: D,
) -> core::result::Result<[u8; 300], D::Error>
where
D: serde::Deserializer<'de>,
{
/* ... */
}
/* ... */The serialize_with attribute should only be emitted if there is a Serialize derive on the data structure, and deserialize_with should only be emitted if there is a Deserialize derive.
Neither attribute should be emitted for a field with array type with literal size that we can see is 32 or smaller.
Attributes do need to be emitted for all arrays of const size not visible to the macro, for example arr_unknown: [u8; BUFFER_SIZE].
Optionally, also support type aliased arrays by specifying the array size in an attribute.
pub const BUFSIZE: usize = 1024;
pub type Buffer = [u8; BUFSIZE];
#[make_big_arrays_work]
#[derive(Serialize, Deserialize)]
struct S {
#[big_array(BUFSIZE)]
buffer: Buffer,
}