1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::Expr;
6use syn::parse::Parse;
7use syn::parse_macro_input;
8use syn::{Error, Ident, Token, parse::ParseStream};
9
10#[cfg(any(feature = "def_cn"))]
11fn get_def_lang() -> Box<str> {
12 Box::from("cn")
13}
14#[cfg(any(feature = "def_en"))]
15fn get_def_lang() -> Box<str> {
16 Box::from("en")
17}
18
19struct Args {
21 cn: Expr,
22 en: Expr,
23}
24
25#[proc_macro]
47pub fn lang_tr(input: TokenStream) -> TokenStream {
48 let args = parse_macro_input!(input as Args);
49 let cn = &args.cn;
50 let en = &args.en;
51
52 let result = match get_def_lang().as_ref() {
53 "cn" => quote! { #cn },
54 "en" => quote! { #en },
55 _ => panic!("必须且只能启用一项默认语言"),
56 };
57
58 TokenStream::from(result)
59}
60
61impl Parse for Args {
62 fn parse(input: ParseStream) -> syn::Result<Self> {
63 let mut cn = None;
64 let mut en = None;
65
66 while !input.is_empty() {
68 let key = input.parse::<Ident>()?;
69 input.parse::<Token![=]>()?;
70 let expr = input.parse::<Expr>()?;
71
72 match key.to_string().as_str() {
73 "cn" => {
74 if cn.is_some() {
75 return Err(Error::new_spanned(key, "Duplicate 'cn' key"));
76 }
77 cn = Some(expr);
78 }
79 "en" => {
80 if en.is_some() {
81 return Err(Error::new_spanned(key, "Duplicate 'en' key"));
82 }
83 en = Some(expr);
84 }
85 _ => return Err(Error::new_spanned(key, "Expected key 'cn' or 'en'")),
86 }
87
88 if input.peek(Token![,]) {
90 input.parse::<Token![,]>()?;
91 } else {
92 break;
93 }
94 }
95
96 Ok(Args {
98 cn: cn.ok_or_else(|| panic!("中文:cn值获取失败,缺少必要参数")).unwrap(),
99 en: en
100 .ok_or_else(|| panic!("English: en value retrieval failed, missing necessary parameters"))
101 .unwrap(),
102 })
103 }
104}