Open lowell-mantisnet opened 1 year ago
Think I got this working for the most part. I essentially made 2 big changes to the Rust ASN1 compiler, hampi
- the generator and the codec derive
procedural macro
. a procedural macro
is a type of macro that auto generates methods for given structs or enums. Unlike the simple declarative functions
I wrote to overwrite the serialize method for particular messages, procedural macros
read in the syntax tree of a struct and auto-generate methods that are associated with an attribute.
To get our ASN1 Enumerated types compiled into usable Rust enums I changed the code in the hampi
's generator and the functoins that defined the procedural macros
for enums.
All changes are inasn-compiler/src/generator/asn/types/base/enumerated.rs.
This change simply changes the object produced from a struct to an enum
While this change creates the internal fields of the struct
Together they can produce the following enum
#[derive(
asn1_codecs_derive :: AperCodec, Debug, Eq, PartialEq, serde :: Serialize, serde :: Deserialize,
)]
#[asn(type = "CHOICE", lb = "0", ub = "4", extensible = false)]
pub enum Cause {
#[asn(key = 0, extended = false)]
RadioNetwork(CauseRadioNetwork),
#[asn(key = 1, extended = false)]
Transport(CauseTransport),
#[asn(key = 2, extended = false)]
Protocol(CauseProtocol),
#[asn(key = 3, extended = false)]
Misc(CauseMisc),
#[asn(key = 4, extended = false)]
Choice_extension(Cause_choice_extension),
}
The other changes are in codecs_derive/src/per/enumerated.rs. in this file I changed generate_aper_codec_for_asn_enumerated
and added generate_variant_decode_tokens
. These two methods together determine how to map a bytes to a struct (encode) and structs to bytes (decode). generate_aper_codec_for_asn_enumerated
now detects the type it's working with: either a struct
or enum
. If it's struct
it will generate the original encode and decode methods. But if it's an enum
it will generate encode and decode methods for an enum. Right now only the decode method works for sure - the autogenerated methods simply performs a match on the integer enum variant and returns the appropriate enum variant. For now the decode function returns an empty tuple for all struct variants. TODO: fix the decode function to return the appropriate variants.
The Problem / Current State
Currently the ASN1 compiler generates structs instead of enums for ASN1 Enumerated types.
i.e. it turns this
into this
When we want something that looks more like this...
The enum will decode into natural strings when serialized to json, while the struct will be displayed as the integer values
How to Generate Rust structs from ASN1
From within the
hampi
root directoryyou could also run
cargo build
insidehampi/examples
. This will generate anf1ap.rs
file inhampi/target
.How it Should be / What Needs to Be Done
To alter the compiler to convert ASN1 Enumerated types to Rust enums we will need to:
encode_enumerated
to encode the enumGenerating Rust Enums from ASN1 Enumerated Types
This piece is partially finished; we can generate the Rust enums, but there might be other field annotations that need to be added.
This was done by changing two blocks of code in asn-compiler/src/generator/asn/types/base/enumerated.rs
I changed this
to
And the generator generated this...
Potential Path forward for Encoding/Decoding
Now that we have a Rust enum we run into problems during the decoding process. The function that generates the encode/decode functions in the
codecs_derive
crate wants that to be a struct. We trigger the compilation error below (currently commented out)(https://github.com/mimetrix/hampi/blob/1b5ec72f32f27c7f0f750eefd3857196a984210d/codecs_derive/src/per/enumerated.rs#L54-L62)
If that error didn't trigger we would hit this macro
and generate something like the below (from a separate ASN1 example)
that
#ty
in the macro above is actually justu8
. I think we just need to generate a ty for enums then generate something that looks more like encode/decode methods generated for ASN1 choice types below:Notice the match statement is being used to map integers to enum types. I was able to overwrite a generated enum for the employee example with the following:
This is the type of method we need to generate after getting past the
Should be a Unit Struct
error above.Key Files
Afterthoughts