wasmtime_versioned_export_macros/
lib.rs

1//! This crate defines macros to easily define and use functions with a
2//! versioned suffix, to facilitate using multiple versions of the same
3//! crate that generate assembly.
4
5use quote::ToTokens;
6
7const VERSION: &str = env!("CARGO_PKG_VERSION");
8
9fn version(value: impl std::fmt::Display) -> String {
10    format!("{}_{}", value, VERSION.replace('.', "_"))
11}
12
13fn versioned_lit_str(value: impl std::fmt::Display) -> syn::LitStr {
14    syn::LitStr::new(version(value).as_str(), proc_macro2::Span::call_site())
15}
16
17#[proc_macro_attribute]
18pub fn versioned_export(
19    _attr: proc_macro::TokenStream,
20    item: proc_macro::TokenStream,
21) -> proc_macro::TokenStream {
22    let mut function = syn::parse_macro_input!(item as syn::ItemFn);
23
24    let export_name = versioned_lit_str(&function.sig.ident);
25    function
26        .attrs
27        .push(syn::parse_quote! { #[unsafe(export_name = #export_name)] });
28
29    function.to_token_stream().into()
30}
31
32#[proc_macro_attribute]
33pub fn versioned_link(
34    _attr: proc_macro::TokenStream,
35    item: proc_macro::TokenStream,
36) -> proc_macro::TokenStream {
37    let mut function = syn::parse_macro_input!(item as syn::ForeignItemFn);
38
39    let link_name = versioned_lit_str(&function.sig.ident);
40    function
41        .attrs
42        .push(syn::parse_quote! { #[link_name = #link_name] });
43
44    function.to_token_stream().into()
45}
46
47#[proc_macro]
48pub fn versioned_stringify_ident(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
49    let ident = syn::parse_macro_input!(item as syn::Ident);
50
51    versioned_lit_str(ident).to_token_stream().into()
52}
53
54#[proc_macro]
55pub fn versioned_suffix(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
56    if !item.is_empty() {
57        return syn::Error::new(
58            proc_macro2::Span::call_site(),
59            "`versioned_suffix!` accepts no input",
60        )
61        .to_compile_error()
62        .into();
63    };
64
65    versioned_lit_str("").to_token_stream().into()
66}