1
Fork 0
mirror of https://github.com/RGBCube/embd-rs synced 2025-07-27 13:37:44 +00:00

Fix and simplify proc macro

This commit is contained in:
RGBCube 2024-01-04 16:59:14 +03:00
parent 23886aa778
commit f2b0e744c4
No known key found for this signature in database
2 changed files with 52 additions and 51 deletions

View file

@ -169,8 +169,10 @@ pub fn __dir_runtime(neighbor: &str, path: &str) -> Dir {
.canonicalize() .canonicalize()
.expect("Failed to canonicalize path"); .expect("Failed to canonicalize path");
let children = read_dir(&directory);
Dir { Dir {
children: read_dir(&directory), children,
path: directory, path: directory,
} }
} }

View file

@ -6,64 +6,72 @@ use std::{
path::PathBuf, path::PathBuf,
}; };
use proc_macro as pm1; use proc_macro::{
self as pm1,
TokenStream,
};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::quote; use quote::{
quote,
ToTokens,
};
use syn::{ use syn::{
parse_macro_input, parse_macro_input,
spanned::Spanned, spanned::Spanned,
LitStr, LitStr,
}; };
#[proc_macro] impl ToTokens for PathBuf {
pub fn dir(input: pm1::TokenStream) -> pm1::TokenStream { fn to_tokens(&self, tokens: &mut TokenStream) {
if false { let raw = self
let path = parse_macro_input!(input as LitStr).value(); .as_str()
.expect("Failed to get the string representation of PathBuf");
return quote! { tokens.append(quote! {
::embed::__include_dir_runtime(file!(), #path) ::std::path::PathBuf::from(#raw)
} });
.into();
} }
}
let caller = dbg!(TokenStream::from(input.clone()).span().source_file().path()); impl ToTokens for Vec<TokenStream> {
fn to_tokens(&self, tokens: &mut TokenStream) {
let input2 = input.clone(); tokens.append(quote! {
let path = parse_macro_input!(input2 as LitStr).value(); vec![#(#self),*]
});
let path = caller
.parent()
.expect("Failed to get the parent of file")
.join(path);
let path_str = path
.to_str()
.expect("Failed to get the string representation of PathBuf");
if path_str.ends_with(".") {
return syn::Error::new_spanned(
TokenStream::from(input),
"Can't embed current file as it is not a directory",
)
.to_compile_error()
.into();
} }
}
let children = read_dir(&path, &path); pub fn dir_debug(input: pm1::TokenStream) -> pm1::TokenStream {
let children_tokens = quote! { let path = parse_macro_input!(input as LitStr).value();
vec![#(#children),*]
quote! {
::embed::__include_dir_runtime(file!(), #path)
}; };
}
pub fn dir_release(input: pm1::TokenStream) -> pm1::TokenStream {
let neigbor = TokenStream::from(input.clone()).span().source_file().path();
let path = parse_macro_input!(input as LitStr).value();
let base = neighbor.parent().expect("Failed to get the parent of file");
let directory = base
.join(path)
.canonicalize()
.expect("Failed to canonicalize path");
let children = read_dir(&directory);
quote! { quote! {
::embed::Dir { ::embed::Dir {
children: #children_tokens, children: #children,
path: ::std::path::PathBuf::from(#path_str), path: #directory,
} }
} }
.into() .into()
} }
fn read_dir(base: &PathBuf, path: &PathBuf) -> Vec<TokenStream> { fn read_dir(directory: &PathBuf) -> Vec<DirEntry> {
let mut entries = Vec::new(); let mut entries = Vec::new();
for entry in fs::read_dir(path).expect("Failed to list directory contents") { for entry in fs::read_dir(path).expect("Failed to list directory contents") {
@ -71,33 +79,24 @@ fn read_dir(base: &PathBuf, path: &PathBuf) -> Vec<TokenStream> {
let path = entry.path(); let path = entry.path();
let path_str = path
.strip_prefix(base)
.expect("Failed to strip prefix of path")
.to_str()
.expect("Failed to get the string representation of PathBuf");
let filetype = fs::metadata(&path) let filetype = fs::metadata(&path)
.expect("Failed to get file metadata") .expect("Failed to get file metadata")
.file_type(); .file_type();
if filetype.is_dir() { if filetype.is_dir() {
let children = read_dir(base, &path); let children = read_dir(&path);
let children_tokens = quote! {
vec![#(#children),*]
};
entries.push(quote! { entries.push(quote! {
::embed::DirEntry::Dir(::embed::Dir { ::embed::DirEntry::Dir(::embed::Dir {
children: #children_tokens, children: #children,
path: ::std::path::PathBuf::from(#path_str), path: #path,
}) })
}); });
} else if filetype.is_file() { } else if filetype.is_file() {
entries.push(quote! { entries.push(quote! {
::embed::DirEntry::File(::embed::File { ::embed::DirEntry::File(::embed::File {
content: include_bytes!(#path_str).to_vec(), content: include_bytes!(#path_str).to_vec(),
path: ::std::path::PathBuf::from(#path_str), path: #path,
}) })
}); });
} }