lers_windows_macro/
lib.rs

1use proc_macro::TokenStream;
2
3use quote::quote;
4use syn::{Data, DeriveInput, Fields, parse_macro_input, Path};
5
6#[proc_macro_derive(FromInto)]
7/// # 为单匿名属性结构体实现From和Into
8pub fn from_into(_input: TokenStream) -> TokenStream {
9    let ast: DeriveInput = parse_macro_input!(_input as DeriveInput);
10    let _self = &ast.ident;
11    let _other = match ast.data {
12        Data::Struct(ref data) => {
13            match data.fields {
14                Fields::Unnamed(ref fields) => {
15                    if fields.unnamed.is_empty() {
16                        panic!("There is no unnamed parameter in struct")
17                    }
18                    if fields.unnamed.iter().count().ne(&1) {
19                        panic!("There are more than one unnamed parameter in struct")
20                    } else {
21                        fields.unnamed.first().unwrap()
22                    }
23                }
24                _ => panic!("There is no unnamed parameter in struct")
25            }
26        }
27        _ => panic!("This is not a struct")
28    };
29    let gen = quote! {
30        impl From<#_other> for #_self{
31            fn from(value: #_other) -> Self{
32                Self(value)
33            }
34        }
35        impl Into<#_other> for #_self{
36            fn into(self) -> #_other{
37                self.0
38            }
39        }
40    };
41    gen.into()
42}
43
44#[proc_macro_attribute]
45/// # 自动将传入参数包装为const attribute
46pub fn self_attr(_attr: TokenStream, item: TokenStream) -> TokenStream
47{
48    let args = _attr.to_string();
49    let mut func = parse_macro_input!(item as syn::ItemImpl);
50    let _self = &func.self_ty;
51    for arg in args.split(",") {
52        let attr = syn::parse_str::<Path>(arg).expect("4").segments.last().expect("5").clone();
53        let target_attr = syn::parse_str::<Path>(arg).expect("3");
54        func.items.push(syn::parse2(quote!(pub const #attr: #_self = #_self(#target_attr);)).expect("2"));
55    }
56    quote!( #func ).into()
57}
58
59#[allow(non_snake_case)]
60#[proc_macro]
61/// # 将字符串转换为PCWSTR类型
62/// ## 依赖
63/// windows 和 widestring
64/// ## 参数
65/// - input: `&str`和`vec<u16>`
66/// - output: `PCWSTR`
67/// ## 注意
68/// 使用`vec<u16>`时,需要在前面加上vec以便区别开来
69/// 例如:
70/// ```
71/// use windows_macro::PCWSTR;
72/// let s:Vec<u16> = Vec::new();
73/// PCWSTR!(vec s);
74/// ```
75pub fn PCWSTR(input: TokenStream) -> TokenStream {
76    let input_str = input.to_string();
77    // 使用正则表达式或其他方法来判断输入形式
78    if input_str.starts_with("vec") {
79        // 处理输入是 vec 的情况
80        let trim_input = input_str.trim_start_matches("vec").trim();  // 去除 "vec" 并去除空格
81        let output = format!("windows::core::PCWSTR::from_raw(widestring::U16CString::from_vec({}).unwrap().into_raw())", trim_input);
82        output.parse().unwrap()
83    } else {
84        // 处理其他情况
85        let output = format!("windows::core::PCWSTR::from_raw(widestring::U16CString::from_str({}).unwrap().into_raw())", input_str);
86        output.parse().unwrap()
87    }
88}
89
90#[allow(non_snake_case)]
91#[proc_macro]
92/// # 将字符串转换为PWSTR类型
93/// ## 依赖
94/// windows 和 widestring
95/// ## 参数
96/// - input: `&str`和`vec<u16>`
97/// - output: `PWSTR`
98/// ## 注意
99/// 使用`vec<u16>`时,需要在前面加上vec以便区别开来
100/// 例如:
101/// ```
102/// use windows_macro::PWSTR;
103/// let s:Vec<u16> = Vec::new();
104/// PWSTR!(vec s);
105/// ```
106pub fn PWSTR(input: TokenStream) -> TokenStream {
107    let input_str = input.to_string();
108    // 通过输入的形式进行区分
109    if input_str.starts_with("vec") {
110        let trim_input = input_str.trim_start_matches("vec").trim();
111        let output = format!("windows::core::PWSTR::from_raw(widestring::U16CString::from_vec({}).unwrap().into_raw())", trim_input);
112        output.parse().unwrap()
113    } else {
114        let output = format!("windows::core::PWSTR::from_raw(widestring::U16CString::from_str({}).unwrap().into_raw())", input_str);
115        output.parse().unwrap()
116    }
117}