librasn / compiler

An ASN1 compiler producing Rust bindings for the rasn framework
Other
10 stars 7 forks source link
asn1 ber compiler der per rasn rust uper

Rasn compiler

crates.io Help Wanted Documentation

Try compiling some ASN.1 online.

The rasn-compiler library is a parser combinator that parses ASN.1 specifications and outputs bindings for ASN.1 data elements using pluggable backends. Currently, the compiler can output:

The compiler heavily relies on the great library nom for its basic parsers. The parser has been designed to generate bindings for ASN.1 and it should not be used as a validating tool for ASN.1 modules.

Example

In order to compile ASN.1 in your build process, invoke the rasn-compiler in your build.rs build script.

// 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 */ }
    }
}

Configuring the Backend

The compiler backends can be configured by instantiating the compiler using the Compiler::new_with_config constructor.

rasn Backend Configuration

The RasnBackend configuration supports the following parameters:

Creating a Custom Backend

The compiler's backend can be replaced with a custom backend to generate bindings for a different language or framework. Backends must implement the Backend trait that rasn-compiler exports.

// 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

The rasn-compiler provides a CLI application that can be activated with the cli cargo feature. Run ./rasn_compiler_cli -h for usage info.

ASN1 Support

ASN1 is a complex standard, and not all of its features and encoding rules are supported, yet.

Currently, rasn supports the following encoding rules:

rasn and the rasn-compiler support the following ASN1 features:

Types

Constraints

Misc

Troubleshooting

If you have trouble generating correct bindings: