rdrive_macro_utils/
lib.rs1extern 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 let path_str = format!("{}::DriverRegister", use_prefix.trim_end_matches("::"));
43 let type_register: syn::Path = parse_str(&path_str).expect("Failed to parse path");
44
45 let path_driver_kind = format!("{}::DriverKind", use_prefix.trim_end_matches("::"));
46 let type_driver_kind: syn::Path = parse_str(&path_driver_kind).expect("Failed to parse path");
47
48 let path_probe_kind = format!("{}::register::ProbeKind", use_prefix.trim_end_matches("::"));
49 let type_probe_kind: syn::Path = parse_str(&path_probe_kind).expect("Failed to parse path");
50
51 let section = link_section.unwrap_or(".driver.register");
52
53 quote! {
54
55 pub mod #mod_name{
56 use super::*;
57 use #type_driver_kind;
58 use #type_probe_kind;
59
60 #[unsafe(link_section = #section)]
61 #[unsafe(no_mangle)]
62 #[used(linker)]
63 pub static #static_name: #type_register = #type_register{
64 #input
65 };
66 }
67 }
68 .into()
69}