anydir_macro/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, LitStr};
4
5/// Embed a directory at compile time
6#[proc_macro]
7pub fn embed_dir(input: TokenStream) -> TokenStream {
8    // Parse the input as a string literal
9    let input = parse_macro_input!(input as LitStr);
10    let dir_path = input.value();
11
12    // Generate a unique identifier for the static variable
13    let var_name = sanitize_identifier(&dir_path);
14
15    let var_ident = syn::Ident::new(&var_name, proc_macro2::Span::call_site());
16
17    // Generate the code
18    let expanded = quote! {
19        {
20            use include_dir::include_dir;
21            static #var_ident: include_dir::Dir = include_dir!(#dir_path);
22            &#var_ident
23        }
24    };
25
26    TokenStream::from(expanded)
27}
28
29fn sanitize_identifier(s: &str) -> String {
30    let mut result = String::from("DIR_");
31    for c in s.chars() {
32        if c.is_ascii_alphanumeric() {
33            result.push(c.to_ascii_uppercase());
34        } else {
35            result.push('_');
36        }
37    }
38    result
39}