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(
12    input: TokenStream,
13    use_prefix: &str,
14    link_section: Option<&str>,
15) -> TokenStream {
16    let input = proc_macro2::TokenStream::from(input);
17    let mut name = None;
18
19    {
20        let mut it = input.clone().into_iter();
21        while let Some(t) = it.next() {
22            if let proc_macro2::TokenTree::Ident(i) = t {
23                if i == "name" {
24                    it.next();
25                    if let Some(proc_macro2::TokenTree::Literal(l)) = it.next() {
26                        let l = l.to_string();
27                        let l = l.trim_matches('"');
28                        name = Some(l.to_string());
29                        break;
30                    }
31                }
32            }
33        }
34    }
35
36    let st_name = name.unwrap_or_default().replace("-", "_").replace(" ", "_");
37
38    let static_name = format_ident!("DRIVER_{}", st_name.to_uppercase());
39    let mod_name = format_ident!("__{}", st_name.to_lowercase());
40
41    // 解析路径
42    let path_register = format!("{}::register", use_prefix.trim_end_matches("::"));
43
44    let path_str = format!("{}::DriverRegister", &path_register);
45    let type_register: syn::Path = parse_str(&path_str).expect("Failed to parse path");
46
47    let path_probe_level = format!("{}::ProbeLevel", &path_register);
48    let type_probe_level: syn::Path = parse_str(&path_probe_level).expect("Failed to parse path");
49
50    let path_probe_priority = format!("{}::ProbePriority", &path_register);
51    let type_probe_priority: syn::Path =
52        parse_str(&path_probe_priority).expect("Failed to parse path");
53
54    let path_probe_kind = format!("{}::ProbeKind", &path_register);
55    let type_probe_kind: syn::Path = parse_str(&path_probe_kind).expect("Failed to parse path");
56
57    let section = link_section.unwrap_or(".driver.register");
58
59    quote! {
60        #[allow(unused)]
61        pub mod #mod_name{
62            use super::*;
63            use #type_probe_level;
64            use #type_probe_priority;
65            use #type_probe_kind;
66
67            #[unsafe(link_section = #section)]
68            #[unsafe(no_mangle)]
69            #[used(linker)]
70            pub static #static_name: #type_register = #type_register{
71                #input
72            };
73        }
74    }
75    .into()
76}