I am happy to announce the first release of 'hampi - Rust ASN.1 toolkit'. This is a collection of three crates -
- ASN.1 Compiler - for generating Rust code from ASN.1 Specifications.
- ASN.1 Codecs - for supporting various encoding formats for ASN.1 like PER, DER etc.
- ASN.1 Codecs Derive Macros - Derive Macros for automatically generating the codec code. (Think of it like
serdebut for ASN.1 Types.
This is a first release and generated code can be used to decode actual protocol data, but a few features are still missing and this is in active development.
For More details Please check -
Majority of the ASN.1 crates out there deal with DER encoding, however to the best of my knowledge, there is no full featured ASN.1 Compiler ( Compiler that can translate ASN.1 specification to Rust structs and implementing Codecs for various encoding rules.). Also, there is only one open source ASN.1 Compiler that supports features like - Information Object Classes, Parameterized Types - but that generates - asn1c, but does not generate Rust code.
Actual compile times are really fast - The entire NGAP ASN.1 specification gets compiled under 1 sec, but as such compile time is not really a benchmark for how good the generated code is. However the decoder itself is reasonably fast for the first implementation. I have been able to do a really quick benchmark for a single NGAP packet decode and compare three implementations.
- Rust codec implementation using the compiler and codec above - fastest
- Rust bindings for C structures generated using
bindgen- About 20-30% slower and uses some
- Go based APER decode using aper module - Order of magnitude slower. This is mainly because this uses runtime reflection, whereas the Rust code does not use Runtime reflection.
Thus it is definitely worth pursuing this further
Right now there is support for APER decoder, APER encoder is WIP and support for other codecs will be added soon. The choice of APER decoder was motivated by 3GPP protocol specifications which use APER encodings.
This is one of my first Rust projects, so it's quite likely that the code might look like a rookie code! Any feedback is welcome.