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}