Add code-generator proto

This commit is contained in:
moznion
2020-11-24 02:03:11 +09:00
parent 6c7012c609
commit 3eab4f16b1
3 changed files with 176 additions and 0 deletions

53
Cargo.lock generated
View File

@@ -1,5 +1,14 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "autocfg"
version = "1.0.1"
@@ -69,6 +78,15 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748"
[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
dependencies = [
"unicode-width",
]
[[package]]
name = "getrandom"
version = "0.1.15"
@@ -293,10 +311,12 @@ name = "radius-rs"
version = "0.1.0"
dependencies = [
"chrono",
"getopts",
"log",
"md5",
"num_enum",
"rand",
"regex",
"thiserror",
"tokio",
]
@@ -348,6 +368,24 @@ version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "regex"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
[[package]]
name = "scopeguard"
version = "1.1.0"
@@ -424,6 +462,15 @@ dependencies = [
"syn",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
dependencies = [
"lazy_static",
]
[[package]]
name = "time"
version = "0.1.44"
@@ -477,6 +524,12 @@ dependencies = [
"serde",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"

View File

@@ -14,3 +14,5 @@ num_enum = "0.5.1"
tokio = { version = "0.3.4", features = ["full"] }
log = "0.4.11"
thiserror = "1.0"
regex = "1"
getopts = "0.2"

121
src/bin/code_gen.rs Normal file
View File

@@ -0,0 +1,121 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::BufRead;
use std::path::Path;
use std::{env, io, process};
use getopts::Options;
use regex::Regex;
const ATTRIBUTE_KIND: &str = "ATTRIBUTE";
const VALUE_KIND: &str = "VALUE";
#[derive(Debug)]
struct RadiusAttribute {
name: String,
identifier: u16,
typ: String,
is_encrypt: bool,
}
#[derive(Debug)]
struct RadiusValue {
name: String,
identifier: u16,
}
fn print_usage(program: &str, opts: &Options) {
let brief = format!("Usage: {} FILE [options]", program);
print!("{}", opts.usage(&brief));
process::exit(0);
}
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where
P: AsRef<Path>,
{
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}
fn main() {
let args: Vec<String> = env::args().collect();
let program = args[0].clone();
let mut opts = Options::new();
let matches = opts
.parse(&args[1..])
.unwrap_or_else(|f| panic!(f.to_string()));
let dict_file_path = matches.free[0].clone();
let (radius_attributes, radius_attribute_to_values) = parse_dict_file(dict_file_path).unwrap();
println!("{:?}", radius_attributes);
println!("{:?}", radius_attribute_to_values);
}
type DictParsed = (Vec<RadiusAttribute>, HashMap<String, Vec<RadiusValue>>);
fn parse_dict_file(dict_file_path: String) -> Result<DictParsed, String> {
let line_filter_re = Regex::new(r"^(?:#.*|)$").unwrap();
let tabs_re = Regex::new(r"\t+").unwrap();
let mut radius_attributes: Vec<RadiusAttribute> = Vec::new();
let mut radius_attribute_to_values: HashMap<String, Vec<RadiusValue>> = HashMap::new();
let lines = read_lines(dict_file_path).unwrap();
for line_result in lines {
let line = line_result.unwrap();
if line_filter_re.is_match(line.as_str()) {
continue;
}
let items = tabs_re.split(line.as_str()).collect::<Vec<&str>>();
if items.len() < 4 {
return Err("the number of items is lacked in a line".to_owned());
}
let kind = items[0];
match kind {
ATTRIBUTE_KIND => {
let type_descriptions = items[3].split(' ').collect::<Vec<&str>>();
let typ = type_descriptions[0].to_string();
let is_encrypt = if type_descriptions.len() >= 2 {
type_descriptions[1] == "encrypt=1" // FIXME: ad-hoc!!!
} else {
false
};
radius_attributes.push(RadiusAttribute {
name: items[1].to_string(),
identifier: items[2].parse().unwrap(),
typ,
is_encrypt,
});
}
VALUE_KIND => {
let attribute_name = items[1].to_string();
let name = items[2].to_string();
let radius_value = RadiusValue {
name,
identifier: items[3].parse().unwrap(),
};
match radius_attribute_to_values.get_mut(&attribute_name) {
None => {
radius_attribute_to_values
.insert(attribute_name.clone(), vec![radius_value]);
}
Some(vec) => {
vec.push(radius_value);
}
};
}
_ => return Err(format!("unexpected kind has come => {}", kind)),
}
}
Ok((radius_attributes, radius_attribute_to_values))
}