Closed Manishearth closed 2 years ago
For enums I can imagine us having derive(ULE)
apply repr(u8)
and just do transmutes. For larger enums this will fail and we'll have to have derive(AsULE)
instead, but enums that large are not common anyway.
This will likely be a proc macro attribute, not a custom derive, with the proc macro attribute generating the ULE type. E.g. #[gen_var_ule(FooULE)]
or something. Writing the ULE type correctly can be tricky so we probably need the proc macro to generate that part too, not just the ULE implementation.
Splitting this into different tasks it may have to do:
repr(packed)
struct containing ULE fieldsPlainOldULE<n>
wrapper with validation, perhaps requiring numeric values to be prespecified so that people don't accidentally break stability by reordering[u8]
at the end and additional private info about the indices for the individual DSTs contained. Unlike the single-dst case we won't be able to allow for easy access to the field directly, but we can add methods, and as usual folks can use the FromVarULE
implFromVarULE
, but this also seems best left to manual impls.For ULE types it would generate:
ULE
and AsULE
implementationsZeroMapKV
implementationFor VarULE types it would generate:
VarULE
implementationEncodeAsVarULE
and FromVarULE
implementationsWe may also need #[derive(ULE)]
that allows wrapping ULE types with more ULE types, in case you wish to implement a custom conversion. Ideally you can also #[generate_serde(target)]
on it to generate appropriate ser/de impls.
As for bit packing and enums, I think the way to do this is:
BITS
constant on ULE
that specifies the number of bits actually needed by the typerepr(packed)
struct of ULEs.#[zerovec::bits(4)]
on a field, the custom derive will instead:
zerovec::bits
fieldsBITS
matches the given bitsizestruct BitPacker([u8; N])
to store the bits field, which has unsafe fn get_ule<U: ULE>(bit: usize)
getting a ULE U
at offset bit
Dataful enums can then be done by mandating that all fields are marked with zerovec::bits
and doing their own discriminantful bitpacking. VarULE for these will involve generating a more complex type, but it's still doable.
The design can be found in the design doc: https://github.com/unicode-org/icu4x/blob/main/utils/zerovec/design_doc.md#proc-macros
Part of https://github.com/unicode-org/icu4x/issues/1082
Depends on https://github.com/unicode-org/icu4x/issues/1078
It would be nice to be able to write:
and have it generate