use std::{ collections::BTreeMap, fmt::Debug, fs::File, io::{BufReader, BufWriter, Write}, path::Path, }; use fancy_regex::Regex; use once_cell::sync::Lazy; use rustypipe::{model::Language, timeago::TimeUnit}; use serde::Deserialize; const DICT_PATH: &str = "testfiles/date/dictionary.json"; const TARGET_FILE: &str = "src/dictionary.rs"; type Dictionary = BTreeMap; #[derive(Debug, Deserialize)] struct DictEntry { #[serde(default)] equivalent: Vec, timeago_tokens: BTreeMap, } fn parse_tu(tu: &str) -> (u8, Option) { static TU_PATTERN: Lazy = 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), } } fn read_dict() -> Dictionary { let json_file = File::open(DICT_PATH).unwrap(); serde_json::from_reader(BufReader::new(json_file)).unwrap() } // #[test] fn t_gen() { let dict = read_dict(); let code_head = r#"// This file is automatically generated. DO NOT EDIT. use crate::{ model::Language, timeago::{TaToken, TimeUnit}, }; "#; let mut code_timeago_tokens = r#"#[rustfmt::skip] pub(crate) fn get_timeago_tokens(lang: Language) -> phf::Map<&'static str, TaToken> { match lang { "# .to_owned(); dict.iter().for_each(|(lang, entry)| { // Create a map for the language let mut map = 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) => map.entry( &txt, &format!("TaToken {{ n: {}, unit: Some(TimeUnit::{:?}) }}", n, unit), ), None => map.entry(&txt, &format!("TaToken {{ n: {}, unit: None }}", n)), }; }); let mut selector = format!("Language::{:?}", lang); entry.equivalent.iter().for_each(|eq| { selector += &format!(" | Language::{:?}", eq); }); let code_map = &map.build().to_string().replace('\n', "\n "); code_timeago_tokens += &format!("{} => {},\n ", selector, code_map); }); code_timeago_tokens = code_timeago_tokens.trim_end().to_owned() + "\n }\n}\n"; let code = format!("{}\n{}", code_head, code_timeago_tokens); std::fs::write(TARGET_FILE, code).unwrap(); }