As one of the authors of those libraries I think I can provide some perspective on why there are so many libraries in this space ![]()
Firstly, I think it’s important to understand that ASN.1 is an incredibly complex set of languages, codecs, and data models, both to describe and implement, and it’s an incredible effort to fully support all it has to offer, and while it is a standardised format, it’s complexity allows a wide variety of different encoders and decoders. So it’s quite easy for someone’s library to not be suitable for a given desire, some may want more specificity to the point of only caring about a single standard, others more generic APIs.
Also important to understand that before you could put ASN.1 in std, we’d need equivalents for all of ASN.1’s types like bit strings in std first. Getting all of those in std would take significant design work and consensus building to get those merged and stabilised. So while ideally it might be great if there was a single reliable implementation, the chances of it happening in std are slim to none, and probably still couldn’t cover every use case.
Not to be the bearer of bad news, but it’s actually not possible to correctly implement an ASN.1 parsing library with Serde. I know this because I spent weeks trying to build one, and reached fundamental limits (as well as needing some ugly workarounds) in Serde’s design such as correctly handling Option types in structs, which requires more information than serde can give you. So any library using serde for ASN.1 will be incorrect/incomplete.
As an aside, I would recommend checking out my crate rasn, despite the sub 10k download count, I’m pretty sure it’s only crate in that list that also supports BER and CER, and correctly handles lots of edge cases that most of the crates don’t handle correctly when I reviewed their implementations.
It’s also much more ecosystem friendly, as its designed similarly to serde‘s traits, which allows you to have different encoders accept the same ASN.1 type, so if you needed your own encoder you could still use types defined with rasn‘s traits. This is also what lets you define and have the same type encodable to BER, CER, and DER from a single trait implementation.