type_macro/
lib.rs

1#![allow(unstable)]
2use proc_macro::{Span, TokenStream};
3use std::fs;
4use std::path::Path;
5use std::time::SystemTime;
6
7use quote::quote;
8use syn::{parse_macro_input, DeriveInput};
9
10
11fn read_env_path() -> String {
12    let out_dir = std::env::var("OUT_DIR").unwrap();
13    let dest_path = Path::new(&out_dir).join("config.txt");
14    let result = fs::read_to_string(&dest_path);
15    result.unwrap_or_else(|_| "default_path".to_string())
16}
17
18
19#[proc_macro_attribute]
20pub fn TS(attr: TokenStream, item: TokenStream) -> TokenStream {
21    let path = read_env_path();
22    match path.as_str() {
23        "default_path" => {}
24        _ => {
25            let item_clone = item.clone();
26            let input = parse_macro_input!(item_clone as DeriveInput);
27            // 获取结构体名称
28            let name = &input.ident;
29            // 处理字段
30            let fields = if let syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Named(fields), .. }) = input.data {
31                fields.named.iter().map(|f| {
32                    let field_name = &f.ident;
33                    let field_type = &f.ty;
34                    quote! {
35                #field_name: #field_type,
36            }
37                }).collect::<Vec<_>>()
38            } else {
39                Vec::new()
40            };
41
42            // 生成 TypeScript 接口代码
43            let ts_code = quote! {
44        interface #name {
45            #(#fields)*
46        }
47    };
48            let string = ts_code.to_string();
49            // 获取文件名
50            // let span = Span::call_site();
51            // let filename = span.source_file().path().file_name()
52            //     .and_then(|f| f.to_str())
53            //     .unwrap_or(&name.to_string());
54
55            let path_name = Path::new(&path).join(format!("{}.ts", attr.to_string()));
56
57            match fs::exists(&path_name) {
58                Ok(b) => {
59                    if !b {
60                        fs::write(&path_name, &string).expect("Unable to write file");
61                    }
62                }
63                Err(_) => {}
64            }
65
66            fs::write("D:\\gitee\\tauri-rust-vue\\output.txt",
67                      format!("input:{:?}\n\
68              ATTR:{:?}\n\
69              PATH:{:?}\n\
70              ", string, attr.to_string(), path_name,
71                      ))
72                .expect("TODO: panic message");
73        }
74    }
75    item
76}