move codegen to separate crate
This commit is contained in:
parent
8548bc81e9
commit
d6cfc7e914
15 changed files with 423 additions and 243 deletions
118
codegen/src/gen_dictionary.rs
Normal file
118
codegen/src/gen_dictionary.rs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
use std::fmt::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use fancy_regex::Regex;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustypipe::timeago::TimeUnit;
|
||||
|
||||
use crate::util;
|
||||
|
||||
const TARGET_PATH: &str = "src/dictionary.rs";
|
||||
|
||||
fn parse_tu(tu: &str) -> (u8, Option<TimeUnit>) {
|
||||
static TU_PATTERN: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(\d*)(\w?)$").unwrap());
|
||||
match TU_PATTERN.captures(tu).unwrap() {
|
||||
Some(cap) => (
|
||||
cap.get(1).unwrap().as_str().parse().unwrap_or(1),
|
||||
match cap.get(2).unwrap().as_str() {
|
||||
"s" => Some(TimeUnit::Second),
|
||||
"m" => Some(TimeUnit::Minute),
|
||||
"h" => Some(TimeUnit::Hour),
|
||||
"D" => Some(TimeUnit::Day),
|
||||
"W" => Some(TimeUnit::Week),
|
||||
"M" => Some(TimeUnit::Month),
|
||||
"Y" => Some(TimeUnit::Year),
|
||||
"" => None,
|
||||
_ => panic!("invalid time unit: {}", tu),
|
||||
},
|
||||
),
|
||||
None => panic!("invalid time unit: {}", tu),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_dictionary(project_root: &Path) {
|
||||
let dict = util::read_dict(project_root);
|
||||
|
||||
let code_head = r#"// This file is automatically generated. DO NOT EDIT.
|
||||
use crate::{
|
||||
model::Language,
|
||||
timeago::{DateCmp, TaToken, TimeUnit},
|
||||
};
|
||||
|
||||
pub struct Entry {
|
||||
pub by_char: bool,
|
||||
pub timeago_tokens: phf::Map<&'static str, TaToken>,
|
||||
pub date_order: &'static [DateCmp],
|
||||
pub months: phf::Map<&'static str, u8>,
|
||||
pub timeago_nd_tokens: phf::Map<&'static str, TaToken>,
|
||||
}
|
||||
"#;
|
||||
|
||||
let mut code_timeago_tokens = r#"#[rustfmt::skip]
|
||||
pub fn entry(lang: Language) -> Entry {
|
||||
match lang {
|
||||
"#
|
||||
.to_owned();
|
||||
|
||||
dict.iter().for_each(|(lang, entry)| {
|
||||
// Match selector
|
||||
let mut selector = format!("Language::{:?}", lang);
|
||||
entry.equivalent.iter().for_each(|eq| {
|
||||
let _ = write!(selector, " | Language::{:?}", eq);
|
||||
});
|
||||
|
||||
// Timeago tokens
|
||||
let mut ta_tokens = phf_codegen::Map::<&str>::new();
|
||||
entry.timeago_tokens.iter().for_each(|(txt, tu_str)| {
|
||||
let (n, unit) = parse_tu(tu_str);
|
||||
match unit {
|
||||
Some(unit) => ta_tokens.entry(
|
||||
txt,
|
||||
&format!("TaToken {{ n: {}, unit: Some(TimeUnit::{:?}) }}", n, unit),
|
||||
),
|
||||
None => ta_tokens.entry(txt, &format!("TaToken {{ n: {}, unit: None }}", n)),
|
||||
};
|
||||
});
|
||||
|
||||
// Months
|
||||
let mut months = phf_codegen::Map::<&str>::new();
|
||||
entry.months.iter().for_each(|(txt, n_mon)| {
|
||||
months.entry(txt, &n_mon.to_string());
|
||||
});
|
||||
|
||||
// Timeago(ND) tokens
|
||||
let mut ta_nd_tokens = phf_codegen::Map::<&str>::new();
|
||||
entry.timeago_nd_tokens.iter().for_each(|(txt, tu_str)| {
|
||||
let (n, unit) = parse_tu(tu_str);
|
||||
match unit {
|
||||
Some(unit) => ta_nd_tokens.entry(
|
||||
txt,
|
||||
&format!("TaToken {{ n: {}, unit: Some(TimeUnit::{:?}) }}", n, unit),
|
||||
),
|
||||
None => ta_nd_tokens.entry(txt, &format!("TaToken {{ n: {}, unit: None }}", n)),
|
||||
};
|
||||
});
|
||||
|
||||
// Date order
|
||||
let mut date_order = "&[".to_owned();
|
||||
entry.date_order.chars().for_each(|c| {
|
||||
let _ = write!(date_order, "DateCmp::{}, ", c);
|
||||
});
|
||||
date_order = date_order.trim_end_matches([' ', ',']).to_owned() + "]";
|
||||
|
||||
let code_ta_tokens = &ta_tokens.build().to_string().replace('\n', "\n ");
|
||||
let code_ta_nd_tokens = &ta_nd_tokens.build().to_string().replace('\n', "\n ");
|
||||
let code_months = &months.build().to_string().replace('\n', "\n ");
|
||||
|
||||
let _ = write!(code_timeago_tokens, "{} => Entry {{\n by_char: {:?},\n timeago_tokens: {},\n date_order: {},\n months: {},\n timeago_nd_tokens: {},\n }},\n ",
|
||||
selector, entry.by_char, code_ta_tokens, date_order, code_months, code_ta_nd_tokens);
|
||||
});
|
||||
|
||||
code_timeago_tokens = code_timeago_tokens.trim_end().to_owned() + "\n }\n}\n";
|
||||
|
||||
let code = format!("{}\n{}", code_head, code_timeago_tokens);
|
||||
|
||||
let mut target_path = project_root.to_path_buf();
|
||||
target_path.push(TARGET_PATH);
|
||||
std::fs::write(target_path, code).unwrap();
|
||||
}
|
||||
Reference in a new issue