pay-respects/rule_parser/src/lib.rs

69 lines
1.7 KiB
Rust
Raw Normal View History

2023-07-30 18:40:18 +02:00
use std::path::Path;
use proc_macro::TokenStream;
#[proc_macro]
pub fn parse_rules(input: TokenStream) -> TokenStream {
let directory = input.to_string().trim_matches('"').to_owned();
let rules = get_rules(directory);
let string_hashmap = gen_string_hashmap(rules);
string_hashmap.parse().unwrap()
}
#[derive(serde::Deserialize)]
struct Rule {
command: String,
2023-07-31 10:20:06 +02:00
match_err: Vec<MatchError>,
2023-07-30 18:40:18 +02:00
}
#[derive(serde::Deserialize)]
2023-07-31 10:20:06 +02:00
struct MatchError {
2023-07-30 18:40:18 +02:00
pattern: Vec<String>,
2023-07-31 09:24:46 +02:00
suggest: Vec<String>,
2023-07-30 18:40:18 +02:00
}
fn get_rules(directory: String) -> Vec<Rule> {
let files = std::fs::read_dir(directory).expect("Failed to read directory.");
let mut rules = Vec::new();
for file in files {
let file = file.expect("Failed to read file.");
let path = file.path();
let path = path.to_str().expect("Failed to convert path to string.");
let rule_file = parse_file(Path::new(path));
rules.push(rule_file);
}
rules
}
fn gen_string_hashmap(rules: Vec<Rule>) -> String {
let mut string_hashmap = String::from("HashMap::from([");
for rule in rules {
let command = rule.command.to_owned();
string_hashmap.push_str(&format!("(\"{}\", vec![", command));
2023-07-31 10:20:06 +02:00
for match_err in rule.match_err {
let pattern = match_err
.pattern
.iter()
.map(|x| x.to_lowercase())
.collect::<Vec<String>>();
2023-07-31 10:20:06 +02:00
let suggest = match_err.suggest;
string_hashmap.push_str(&format!(
2023-07-31 09:24:46 +02:00
"(vec![\"{}\"], vec![\"{}\"]),",
pattern.join("\", \""),
2023-07-31 09:24:46 +02:00
suggest.join("\", \"")
));
2023-07-30 18:40:18 +02:00
}
string_hashmap.push_str("]),");
}
string_hashmap.push_str("])");
string_hashmap
}
fn parse_file(file: &Path) -> Rule {
let file = std::fs::read_to_string(file).expect("Failed to read file.");
toml::from_str(&file).expect("Failed to parse toml.")
}