#asn-1 #compiler #ber-der #ber #der #uper

bin+lib rasn-compiler

一个生成用于rasn框架绑定的ASN.1编译器

9个版本

新版本 0.3.2 2024年8月23日
0.3.1 2024年8月7日
0.3.0 2024年5月13日
0.2.0 2024年4月23日
0.1.0 2024年2月1日

#267 in 解析器实现

Download history 13/week @ 2024-05-01 134/week @ 2024-05-08 74/week @ 2024-05-15 108/week @ 2024-05-22 91/week @ 2024-05-29 92/week @ 2024-06-05 78/week @ 2024-06-12 60/week @ 2024-06-19 71/week @ 2024-06-26 156/week @ 2024-07-03 122/week @ 2024-07-10 144/week @ 2024-07-17 20/week @ 2024-07-24 183/week @ 2024-07-31 209/week @ 2024-08-07 29/week @ 2024-08-14

463 每月下载量
用于 rasn-compiler-derive

MIT/Apache

710KB
17K SLoC

Rasn编译器

crates.io Help Wanted Documentation

尝试在线编译一些ASN.1。

rasn-compiler库是一个解析器组合器,它解析ASN.1规范,并使用可插拔后端输出ASN.1数据元素的绑定。目前,编译器可以输出

  • rasn包一起使用的Rust绑定
  • 用于JER编码ASN.1数据元素的TypeScript类型定义

编译器主要依赖于优秀的库nom进行其基本解析器。解析器已被设计用于生成ASN.1的绑定,不应将其用作ASN.1模块的验证工具。

示例

为了在构建过程中编译ASN.1,请在您的build.rs构建脚本中调用rasn-compiler

// build.rs build script
use std::path::PathBuf;
use rasn_compiler::prelude::*;

fn main() {
    // Initialize the compiler with the rust/rasn backend.
    // To use the typescript backend, initialize the compiler using
    // `Compiler::<TypescriptBackend, _>::new()`
    match Compiler::<RasnBackend, _>::new()
        // add a single ASN1 source file
        .add_asn_by_path(PathBuf::from("spec_1.asn"))
        // add several ASN1 source files
        .add_asn_sources_by_path(vec![
            PathBuf::from("spec_2.asn"),
            PathBuf::from("spec_3.asn"),
        ].iter())
        // set an output path for the generated rust code
        .set_output_path(PathBuf::from("./asn/generated.rs"))
        // you may also compile literal ASN1 snippets
        .add_asn_literal(format!(
            "TestModule DEFINITIONS AUTOMATIC TAGS::= BEGIN {} END",
            "My-test-integer ::= INTEGER (1..128)"
        ))
        .compile() {
        Ok(warnings /* Vec<Box<dyn Error>> */) => { /* handle compilation warnings */ }
        Err(error /* Box<dyn Error> */) => { /* handle unrecoverable compilation error */ }
    }
}

配置后端

可以通过使用构造函数Compiler::new_with_config来实例化编译器以配置编译器后端。

rasn后端配置

RasnBackend配置支持以下参数

  • opaque_open_types: bool: [默认: false] ASN.1 开放类型表示为rasn::types::Any类型,该类型包含二进制内容。如果opaque_open_typesfalse,编译器将为所有包含开放类型的Rust类型生成额外的编码/解码方法。例如,具有开放类型字段的SEQUENCE的绑定将包括一个用于显式解码开放类型字段的方法。 非透明开放类型仍然是实验性的。如果您在生成正确的绑定时遇到问题,请切换回透明开放类型。
  • default_wildcard_imports: bool: [默认值: false] 编译器将尝试尽可能接近地匹配ASN.1模块的模块导入依赖关系,仅导入在ASN.1模块中导入的其他模块中的那些类型。如果将default_wildcard_imports设置为true,则编译器将改用通配符*始终导入输入ASN.1模块导入的每个模块的整个模块。

创建自定义后端

可以通过替换编译器的后端来使用自定义后端生成针对不同语言或框架的绑定。后端必须实现由rasn-compiler导出的Backend特质。

// build.rs build script
use std::path::PathBuf;
use rasn_compiler::prelude::*;

// The `Backend` trait requires the implementor to implement `Default`
#[derive(Default)]
struct CustomBackend;

impl Backend for CustomBackend {
    type Config = ();

    const FILE_EXTENSION: &'static str = ".ext";

    fn generate_module(
         &self,
         top_level_declarations: Vec<ToplevelDefinition>,
    ) -> Result<GeneratedModule, GeneratorError> {
        Ok(GeneratedModule::empty())
    }

    fn generate(
        &self,
        tld: ToplevelDefinition
    ) -> Result<String, GeneratorError> {
        Ok(String::new())
    }

    fn config(&self) -> &Self::Config {
        &()
    }

    fn from_config(config: Self::Config) -> Self {
        CustomBackend
    }
}

fn main() {
    // Initialize the compiler
    match Compiler::<CustomBackend, _>::new()
        // add a single ASN1 source file
        .add_asn_by_path(PathBuf::from("spec_1.asn"))
        // add several ASN1 source files
        .add_asn_sources_by_path(vec![
            PathBuf::from("spec_2.asn"),
            PathBuf::from("spec_3.asn"),
        ].iter())
        // set an output path for the generated rust code
        .set_output_path(PathBuf::from("./asn/generated.rs"))
        // you may also compile literal ASN1 snippets
        .add_asn_literal(format!(
            "TestModule DEFINITIONS AUTOMATIC TAGS::= BEGIN {} END",
            "My-test-integer ::= INTEGER (1..128)"
        ))
        .compile() {
        Ok(warnings /* Vec<Box<dyn Error>> */) => { /* handle compilation warnings */ }
        Err(error /* Box<dyn Error> */) => { /* handle unrecoverable compilation error */ }
    }
}

命令行界面(CLI)

rasn-compiler提供了一个可以通过cli cargo特性激活的CLI应用程序。运行./rasn_compiler_cli -h获取使用信息。

ASN1支持

ASN1是一个复杂的标准,其所有功能和编码规则尚未全部支持。

目前,rasn支持以下编码规则

  • 基本编码规则(BER)
  • 规范编码规则(CER)
  • 区分编码规则(DER)
  • 对齐打包编码规则(APER)
  • 非对齐打包编码规则(UPER)
  • JSON编码规则(JER)

rasnrasn-compiler支持以下ASN1功能

类型

  • NULL类型和值
  • BOOLEAN类型和值
  • NumericString类型和值
  • VisibleString类型和值
  • IA5String类型和值
  • GeneralString类型和值
  • UTF8String类型和值
  • BMPString类型和值
  • PRINTABLE STRING类型和值
  • BIT STRING类型和值(十六进制和位字符串声明)
  • OCTET STRING类型和值(十六进制和位字符串声明)
  • OBJECT IDENTIFIER类型和值
  • RELATIVE-OID类型和值
  • SEQUENCE类型和值
  • SET类型和值
  • SEQUENCE OF类型和值
  • SET OF类型和值
  • ENUMERATED类型和值
  • CHOICE类型和值
  • UTCTime类型和值
  • GeneralizedTime类型和值

约束

  • 单值约束
  • 值范围约束
  • 包含子类型约束
  • 大小约束
  • 允许的字母表约束
  • 约束集操作
  • 表约束

其他

  • DEFAULT成员值
  • COMPONENTS OF符号
  • 选择选择类型符号(例如,option-1 < Example-choice
  • 扩展和扩展组
  • 参数化(rasn-compiler 为给定规范中参数化数据元素的调用创建 Rust 表示,即它本身不保留参数化)
  • 信息对象类(然而,它们在 Rust 绑定中未表示)
  • 信息对象
  • 信息对象集合

故障排除

如果您在生成正确绑定时遇到问题

  • 尝试调整可以传递给 Compiler::new_with_config 构造函数的编译器配置
  • 如果可能,在此处创建一个问题,最好附上具有问题的 ASN.1 规范样本

依赖关系

约 2-10MB
约 90K SLoC