AFAIK在Rust中没有(灵活且稳定的)ASN.1 {ser,deser} ialization库,所以我正在考虑制作一个(同时学习Rust)。我的目标是在Rust中使用SNMP(v1-v3)客户端。
在开始之前,我想询问Serde团队或有经验的Serde用户是否可以使用Serde实现ASN.1编解码器。问题是ASN.1中的每个对象都有它自己的标题(TAG
+ LENGTH
),其中TAG
是用户为每种类型定义的,所以iXX或uXX或字节或什么都可以TAG
。
ASN.1对象由tag
,length
和payload
组成。 ASN.1有一组通用(默认)标签,用于整数,浮点数,字节串(以及ASCII字符串)等。我可以坚持原始类型的通用标签,但对于非基本类型(元组,新类型,结构) etc)类型应具有Asn1Info
特征的实现,提供标记和自定义序列化/反序列化功能。
{ser,deser}原始类型的实现是微不足道的,但是如何为复杂的结构(或新类型)实现它呢?他们必须为Asn1Info
。
我查看了asn1-cereal库。它看起来像一个不错的ASN.1实现,提供有用的宏和东西。我不妨在其上工作,而不是从头开始编写所有内容。
我们假设tag
为u8
,Asn1Info特征如下:
pub trait Asn1Info {
fn asn1_tag() -> u8;
}
然后我有一个像pub struct Counter(u32)
这样的新类型,它有自己的应用程序特定标记。然后,我会像这样为Counter做一个impl:
impl Asn1Info for Counter {
fn asn1_tag() -> u8 {
0x41
}
}
现在如何在不手动实施0x41
特征的情况下使用标记Serialize
对其进行序列化?无法向Serializer
注入其他信息,因此我无法重复使用其中的所有非原始序列化方法(如serialize_newtype_variant
)。
如果我不能在Serializer
trait impl中使用Serialize
方法来获取自定义ASN.1对象(特定于应用程序,特定于上下文等),那么就没有办法(或者没有意义)用Serde实现一个有用的ASN.1编解码器,不是吗?