use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator}; use serde_json::Value; use crate::models::{self, recipe::Recipe01}; use std::collections::HashMap; use std::{fs::File, io::Read}; pub trait EnumAsValue { fn name(&self) -> String; fn value(&self) -> T; fn get(val: T) -> Self; } // Change path here! fn extract_tb_config(content: String) -> HashMap { let mut result = HashMap::new(); let lines = content.lines(); for line in lines { let parts: Vec<&str> = line.split('=').collect(); if parts.len() == 2 { result.insert(parts[0].trim().to_string(), parts[1].trim().to_string()); } } result } /// Get config from `.tbcfg` file in current directory pub fn get_config() -> HashMap { // need `.tbcfg` let cfg_result = std::fs::read_to_string("./.tbcfg"); match cfg_result { Ok(cfg) => extract_tb_config(cfg), Err(e) => panic!("Failed to read .tbcfg: {}", e), } } pub fn create_recipe_model_from_file(path: String) -> models::recipe::Recipe { println!("create_recipe_model_from_file: {}", path); let mut file = File::open(path).unwrap(); println!("check file: {}", file.metadata().unwrap().is_file()); let mut data = String::new(); file.read_to_string(&mut data).unwrap(); models::recipe::Recipe::init(data) } pub fn create_recipe_path(country_path: &str, version: usize) -> String { let mut path = String::from(get_config().get("RECIPE_DIR").unwrap()); path.push_str(country_path); path.push_str("/coffeethai02_"); // version path.push_str(&version.to_string()); if country_path != "tha" { path.push('_'); path.push_str(country_path); } path.push_str(".json"); path } pub fn get_all_files_in_directory(directory_path: &str) -> Vec { let mut files = Vec::new(); let dir = std::fs::read_dir(directory_path).unwrap(); for entry in dir { let entry = entry.unwrap(); let path = entry.path(); if path.is_file() { let npath = path.as_os_str().to_str().unwrap().to_string(); println!("pushed {}", npath); files.push(npath); } } files } pub fn filter_files_by_pattern(files: Vec, pattern: &str) -> Vec { files .into_iter() .filter(|file| file.contains(pattern)) .collect() } pub fn get_pd_prefix(country: &str) -> String { match country { "mys" => "12".to_string(), "sgp" => "52".to_string(), "aus" => "51".to_string(), "tha" => "12".to_string(), "hkg" => "54".to_string(), "dubai" => "53".to_string(), "uae" => "53".to_string(), _ => "12".to_string(), } } pub fn get_mat_prefix(country: &str) -> String { match country { "sgp" => "52".to_string(), "aus" => "51".to_string(), "hkg" => "54".to_string(), "dubai" => "53".to_string(), "uae" => "53".to_string(), _ => "".to_string(), } } pub fn check_allowed_change_mat_prefix(mat_id: Value) -> bool { let mat_id_i = mat_id.as_i64().unwrap(); let exception_list = [ 2101, 1031, 1, 9100, 8101, 8102, 8111, 8112, 8113, 8114, 8115, 8116, 8117, 8118, 8119, 8120, 8001, 8002, 8888, 8889, 200000, 201001, 201002, 100004, 0, ]; !exception_list.contains(&mat_id_i) } pub fn change_prefix_by_country( country: &str, mut recipes: Vec>, ) -> Vec { let mut result = Vec::new(); // get prefix first let prefix = get_pd_prefix(country); let mat_prefix = get_mat_prefix(country); // run let updated = recipes .par_iter_mut() .update(|x| { if let Some(x) = x { // change productCode let mut new_product_code = x.productCode.clone(); new_product_code = format!("{}-{}", prefix, new_product_code.split_once('-').unwrap().1); x.productCode = new_product_code; // run through recipes let mut new_recipes_format = Vec::new(); for ele in x.clone().recipes { let mut eled = ele.clone(); if check_allowed_change_mat_prefix(eled.clone().materialPathId) { let new_f = format!("{}{}", mat_prefix, eled.clone().materialPathId); eled.materialPathId = Value::Number(new_f.parse::().unwrap().into()); } new_recipes_format.push(eled); } x.recipes = new_recipes_format; if let Some(s) = x.clone().SubMenu { // let cls = s.clone(); for mut sl in cls.clone() { let mut new_sl_pd = sl.productCode.clone(); new_sl_pd = format!("{}-{}", prefix, new_sl_pd.split_once('-').unwrap().1); sl.productCode = new_sl_pd; let mut new_recipes_sub = Vec::new(); for ele in sl.recipes { let mut eled = ele.clone(); if check_allowed_change_mat_prefix(eled.clone().materialPathId) { let new_f = format!("{}{}", mat_prefix, eled.clone().materialPathId); eled.materialPathId = Value::Number(new_f.parse::().unwrap().into()); } new_recipes_sub.push(eled); } sl.recipes = new_recipes_sub; } x.SubMenu = Some(cls.clone()); } } }) .filter(|x| x.is_some()) .map(|x| x.clone().unwrap()) .collect_vec_list(); // check by update for x in updated.iter() { result.extend_from_slice(x); } result } pub fn valid_country_name() -> Vec<&'static str> { vec!["mys", "sgp", "aus", "tha", "hkg", "dubai", "uae"] } pub fn grep_latest_versions(dir_path: &str) -> Result, std::io::Error> { let mut vs = HashMap::new(); // open dir let entries = std::fs::read_dir(dir_path)? .map(|res| res.map(|e| e.path())) .collect::, std::io::Error>>()?; for e in entries { let path = e.clone().to_str().unwrap().to_string(); let mut cl_path = path.clone(); let path_split = path.split("/").collect::>(); let dir_name = path_split[path_split.len() - 1]; if valid_country_name().contains(&dir_name) { cl_path.push_str("/version"); // read filename let mut file = File::open(cl_path)?; let mut data = String::new(); file.read_to_string(&mut data).unwrap(); vs.insert(dir_name.to_string(), data.parse::().unwrap()); } // expect dir with country } Ok(vs) }