#asn-1 #编译器 #rasn #

rasn-compiler-derive

生成 rasn 框架绑定的宏

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 日

#7#rasn

Download history 27/week @ 2024-04-26 128/week @ 2024-05-10 23/week @ 2024-05-17 6/week @ 2024-05-24 1/week @ 2024-05-31 21/week @ 2024-07-05 3/week @ 2024-07-12 96/week @ 2024-08-02 14/week @ 2024-08-09

110 每月下载量

MIT/Apache

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

创建自定义后端

编译器的后端可以用自定义后端替换,以生成不同语言或框架的绑定。后端必须实现 Backend 特性,该特性由 rasn-compiler 导出。

// 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 应用程序,可以通过 cli cargo 功能激活。运行 ./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.3–3.5MB
~62K SLoC