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 解析器实现
463 每月下载量
用于 rasn-compiler-derive
710KB
17K SLoC
Rasn编译器
rasn-compiler
库是一个解析器组合器,它解析ASN.1规范,并使用可插拔后端输出ASN.1数据元素的绑定。目前,编译器可以输出
编译器主要依赖于优秀的库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_types
为false
,编译器将为所有包含开放类型的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)
rasn
和rasn-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