rasn_compiler/generator/
mod.rs

1//! The `generator` module is responsible for generating rust code that handles
2//! decoding and encoding of the parsed and validated ASN1 data elements.
3//! The `generator` uses string templates for generating rust code.
4
5use std::fmt::Debug;
6
7use crate::{
8    error::CompilerError,
9    intermediate::{ExtensibilityEnvironment, TaggingEnvironment, ToplevelDefinition},
10};
11
12use self::error::GeneratorError;
13
14pub mod error;
15pub mod rasn;
16pub mod typescript;
17
18/// Implementors of the `Backend` trait can be used
19/// as a backend to the compiler in order to create bindings
20/// for other frameworks and languages than the default backend.
21pub trait Backend: Default {
22    type Config: Default + Debug;
23
24    /// File extension that should be used for output file containing the generated bindings.
25    /// For example: `.ts` for Typescript, `.rs` for Rasn bindings.
26    const FILE_EXTENSION: &'static str;
27
28    /// generates bindings for an ASN.1 module
29    /// ### Params
30    /// - `top_level_declarations` vector of [TopLevelDeclaration]s that are defined in the ASN.1 module
31    fn generate_module(
32        &mut self,
33        top_level_declarations: Vec<ToplevelDefinition>,
34    ) -> Result<GeneratedModule, GeneratorError>;
35
36    /// generates bindings for a single ASN.1 item
37    /// ### Params
38    /// - `tld` [TopLevelDeclaration] for which the bindings should be generated
39    fn generate(&self, tld: ToplevelDefinition) -> Result<String, GeneratorError>;
40
41    /// Formats the bindings using the language- or framework-specific linters.
42    /// For example, the Rust backend uses rustfmt for formatting bindings.
43    fn format_bindings(bindings: &str) -> Result<String, CompilerError> {
44        Ok(bindings.to_owned())
45    }
46
47    /// Returns a reference to the backend's config
48    fn config(&self) -> &Self::Config;
49
50    /// Creates a backend from its config
51    fn from_config(config: Self::Config) -> Self;
52
53    /// Creates a backend from its fields.
54    /// Usually, the tagging and extensibility environments do not
55    /// have to be set manually, but will follow the respective module header.
56    fn new(
57        config: Self::Config,
58        tagging_environment: TaggingEnvironment,
59        extensibility_environment: ExtensibilityEnvironment,
60    ) -> Self;
61}
62
63pub struct GeneratedModule {
64    pub generated: Option<String>,
65    pub warnings: Vec<CompilerError>,
66}
67
68impl GeneratedModule {
69    pub fn empty() -> Self {
70        Self {
71            generated: None,
72            warnings: vec![],
73        }
74    }
75}