前端动态菜单原理-Rust版
菜单
二开基座,通过在widgets的index.ts,读取其配置,最后生成一份menu.ts文件,会存放于src/config/menu.ts。

export const menu: Record<string,any>[] = [
{
"name": "追溯报表",
"path": "/information-base/TraceManagement",
"patchName": "TraceManagement",
"icon": "t1",
"notPage": false
},
{
"name": "系统管理",
"path": "/information-base/SystemManagement",
"patchName": "SystemManagement",
"icon": "system",
"notPage": false
}
]
具体细节如下:
use glob::glob;
use regex::Regex;
use serde_json::Value;
use std::collections::HashMap;
use std::env;
use std::fs;
use std::path::PathBuf;
use std::str;
use std::time::Instant;
mod transform;
fn _test_time() {
let start = Instant::now();
let mut bb: u64 = 0;
for index in 1..=1_000_000_000 {
bb += index;
}
let duration = start.elapsed();
println!("Sum in Rust: {}", bb);
println!("Time taken by Rust: {:?}", duration);
}
fn main() {
// _test_time();
// 获取当前时间
let start_time = Instant::now();
let mut menu_js_string = start();
let menu_json_string = &menu_js_string.replace("export const menu = ", "");
let v: Value =
serde_json::from_str(menu_json_string.as_str()).expect("Failed to parse JSON string");
let mut hashmap: HashMap<String, Value> = HashMap::new();
if v.is_array() {
for obj in v.as_array().unwrap() {
let path_clone = &obj["path"].to_string();
let widget_name = path_clone.replace("/standard/", "").replace(r#"""#, "");
hashmap.insert(widget_name, obj.clone());
}
}
let widget_map = serde_json::to_string(&hashmap).unwrap();
menu_js_string.push_str(";\n export const menuMap = ");
menu_js_string.push_str(&widget_map);
write_file(menu_js_string);
let duration = start_time.elapsed();
// 输出执行时间(以毫秒为单位)
println!("执行时间: {} 毫秒", duration.as_millis(),);
}
fn widgets_path() -> Vec<PathBuf> {
let mut ts_files = Vec::new();
for entry in glob("../src/widgets/*/index.ts").expect("Failed to read glob pattern") {
match entry {
Ok(path) => {
ts_files.push(path);
}
Err(e) => {
println!("错误{:?}", e);
continue;
}
}
}
ts_files
}
fn write_file(content: String) {
let _ = fs::write("./src/config/menu.ts", content);
}
fn _read_file(file_path: String) -> String {
let foo = fs::read_to_string(file_path).expect("Failed to read file");
return foo;
}
fn start() -> String {
let ts_files: Vec<PathBuf> = widgets_path();
let new_root_dir = "../";
if let Err(err) = env::set_current_dir(new_root_dir) {
eprintln!("Failed to set new root directory: {}", err);
}
let mut menus_string = String::from("export const menu = [");
for file_path in ts_files {
let file_path_string: std::borrow::Cow<'_, str> = file_path.to_string_lossy();
let file: String = file_path_string.replace("../", "");
// let code = read_file(file.clone());
// dbg!(&content);
let code = transform::swc_transform(file);
let re = Regex::new(r"export default [\s\S]*?;").unwrap();
let re_string = re.captures(&code);
match re_string {
Some(dcode) => {
let code = dcode.get(0).unwrap().as_str();
let re_view = Regex::new(r"\{[\s\S]*?;").unwrap();
let canvas_re_captures = re_view.captures(&code);
let mut menu = String::from("");
if let Some(view) = canvas_re_captures {
let view_code = view.get(0).unwrap().as_str();
menu.push_str("{");
for v in view_code.split("\n") {
let c = String::from(v);
if c.contains("is:") {
let parts = c.split("is:").nth(1);
match parts {
Some(widget_name_str) => {
let widget_name =
widget_name_str.trim().replace('\"', "").replace(",", "\"");
let mut path_str = String::from("\"path\": \"/standard/");
path_str.push_str(&widget_name);
menu.push_str(&path_str);
menu.push_str(",\n");
}
None => println!("The second part does not exist."),
}
}
if c.contains("name:") {
let name = c.trim().replace(",", "").replace("name", "\"name\"");
menu.push_str(&name);
menu.push_str(",\n");
}
if c.contains("icon:") {
let parts = c.split("icon:").nth(1);
match parts {
Some(icon_name_str) => {
let icon_name = icon_name_str
.replace(" ", "\"")
.replace(',', "\"")
.replace("\"\"", "\"");
let mut path_str = String::from("\"icon\":");
path_str.push_str(&icon_name);
menu.push_str(&path_str);
menu.push_str("\n");
}
None => println!("The second part does not exist."),
}
}
}
}
menu.push_str("},\n");
menus_string.push_str(&menu);
}
None => {}
}
}
menus_string.push_str("]");
let menu_format = menus_string.replace("},\n]", "}\n]");
return menu_format;
}