Crates.io | rasn-compiler |
lib.rs | rasn-compiler |
version | 0.6.0 |
source | src |
created_at | 2024-02-01 17:24:37.588102 |
updated_at | 2024-11-10 21:11:51.636661 |
description | An ASN.1 compiler producing bindings for the rasn framework |
homepage | https://librasn.github.io/ |
repository | https://github.com/librasn/compiler.git |
max_upload_size | |
id | 1123355 |
size | 781,590 |
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:
rasn
crateThe 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.
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 */ }
}
}
The compiler backends can be configured by instantiating the compiler using the Compiler::new_with_config
constructor.
rasn
Backend ConfigurationThe RasnBackend
configuration supports the following parameters:
bool
: [Default: false
] ASN.1 Open Types are represented as the rasn::types::Any
type,
which holds a binary content
. If opaque_open_types
is false
, the compiler will generate additional de-/encode methods for
all rust types that hold an open type. For example, bindings for a SEQUENCE
with a field of Open Type value will include a method for explicitly decoding the Open Type field. Non-opaque open types are still
experimental. If you have trouble generating correct bindings, switch back to opaque open types.bool
: [Default: false
] The compiler will try to match module import dependencies
of the ASN.1 module as close as possible, importing only those types from other modules that are imported in the
ASN.1 module. If the default_wildcard_imports
is set to true
, the compiler will instead always import the
entire module using the wildcard *
for each module that the input ASN.1 module imports from.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(
&mut 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 new(
config: Self::Config,
tagging_environment: TaggingEnvironment,
extensibility_environment: ExtensibilityEnvironment,
) -> 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 */ }
}
}
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 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:
NULL
type and valueBOOLEAN
type and valueNumericString
type and valueVisibleString
type and valueIA5String
type and valueGeneralString
type and valueUTF8String
type and valueBMPString
type and valuePrintableString
type and valueBIT STRING
type and value (hex- and bitstring declations)OCTET STRING
type and value (hex- and bitstring declations)OBJECT IDENTIFIER
type and valueRELATIVE-OID
type and valueSEQUENCE
type and valueSET
type and valueSEQUENCE OF
type and valueSET OF
type and valueENUMERATED
type and valueCHOICE
type and valueUTCTime
type and valueGeneralizedTime
type and valueDEFAULT
member valuesCOMPONENTS OF
notationoption-1 < Example-choice
)rasn-compiler
creates rust representations for invocations of the parameterized data
elements in the given spec, i.e. it does not preserve the parameterization itself)If you have trouble generating correct bindings:
Compiler::new_with_config
constructor