1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::path::PathBuf;
use crate::prelude::*;
use clap::{arg, command, Parser};
use colored::Colorize;
use walkdir::WalkDir;
#[derive(clap::Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct CompilerArgs {
/// Specify a directory for the compiler to search for ASN1 modules.
/// The compiler will search recursively for `.asn` and `.asn1` files
#[arg(short, long)]
directory: Option<PathBuf>,
/// Add an ASN1 module by path. Multiple modules can be added by appending "-m PATH_TO_MODULE"
#[arg(short, long = "module", num_args(0..))]
module_files: Vec<PathBuf>,
/// Set the output path for the generated rust module
#[arg(short, long, default_value = ".")]
output_path: PathBuf,
/// Specify which compiler backend to use:
/// - "rasn" [DEFAULT]: generates rust-bindings for the rasn framework
/// - "typescript": generates typescript type definitions
#[arg(short, long, default_value = "rasn")]
backend: String,
}
impl CompilerArgs {
pub fn drive() {
let args = CompilerArgs::parse();
// Read module paths
let mut modules = args.module_files;
// Scan directory, if given
if let Some(dir) = args.directory {
for entry in WalkDir::new(dir)
.follow_links(true)
.into_iter()
.filter_map(|e| e.ok())
{
let file_name = entry.file_name().to_string_lossy();
if file_name.ends_with(".asn") || file_name.ends_with(".asn1") {
println!("Found ASN1 module {} in directory", file_name);
modules.push(entry.into_path());
}
}
}
if modules.is_empty() {
panic!(
"{}",
"Please provide either a valid path to a module or to a directory containing modules."
.red()
)
}
let results = if args.backend == "typescript" {
Compiler::<TypescriptBackend, _>::new()
.add_asn_sources_by_path(modules.into_iter())
.set_output_path(args.output_path)
.compile()
} else {
Compiler::<RasnBackend, _>::new()
.add_asn_sources_by_path(modules.into_iter())
.set_output_path(args.output_path)
.compile()
};
match results {
Ok(warnings) => {
for warning in warnings {
println!(
"{}\n{}",
"Rasn compiler warning:".yellow(),
warning.to_string().yellow()
)
}
}
Err(error) => {
println!(
"{}\n{}",
"Rasn compiler error:".red(),
error.to_string().red()
)
}
}
}
}