rdrive_macro_utils/
lib.rs

1extern crate proc_macro;
2#[macro_use]
3extern crate quote;
4extern crate core;
5extern crate proc_macro2;
6extern crate syn;
7
8use proc_macro::TokenStream;
9use syn::parse_str;
10
11pub fn module_driver_with_linker(input: TokenStream, use_prefix: &str) -> TokenStream {
12    let input = proc_macro2::TokenStream::from(input);
13    let mut name = None;
14
15    {
16        let mut it = input.clone().into_iter();
17        while let Some(t) = it.next() {
18            if let proc_macro2::TokenTree::Ident(i) = t {
19                if i == "name" {
20                    it.next();
21                    if let Some(proc_macro2::TokenTree::Literal(l)) = it.next() {
22                        let l = l.to_string();
23                        let l = l.trim_matches('"');
24                        name = Some(l.to_string());
25                        break;
26                    }
27                }
28            }
29        }
30    }
31
32    let st_name = name.unwrap_or_default().replace("-", "_").replace(" ", "_");
33
34    let static_name = format_ident!("DRIVER_{}", st_name.to_uppercase());
35
36    // 解析路径
37    let path_str = format!("{}::DriverRegister", use_prefix.trim_end_matches("::"));
38    let type_register: syn::Path = parse_str(&path_str).expect("Failed to parse path");
39
40    quote! {
41        #[unsafe(link_section = ".driver.register")]
42        #[unsafe(no_mangle)]
43        #[used(linker)]
44        pub static #static_name: #type_register = #type_register{
45            #input
46        };
47    }
48    .into()
49}