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:
parent
23886aa778
commit
f2b0e744c4
2 changed files with 52 additions and 51 deletions
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
return quote! {
|
|
||||||
::embed::__include_dir_runtime(file!(), #path)
|
|
||||||
}
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
let caller = dbg!(TokenStream::from(input.clone()).span().source_file().path());
|
|
||||||
|
|
||||||
let input2 = input.clone();
|
|
||||||
let path = parse_macro_input!(input2 as LitStr).value();
|
|
||||||
|
|
||||||
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");
|
.expect("Failed to get the string representation of PathBuf");
|
||||||
|
|
||||||
if path_str.ends_with(".") {
|
tokens.append(quote! {
|
||||||
return syn::Error::new_spanned(
|
::std::path::PathBuf::from(#raw)
|
||||||
TokenStream::from(input),
|
});
|
||||||
"Can't embed current file as it is not a directory",
|
}
|
||||||
)
|
|
||||||
.to_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let children = read_dir(&path, &path);
|
impl ToTokens for Vec<TokenStream> {
|
||||||
let children_tokens = quote! {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
vec![#(#children),*]
|
tokens.append(quote! {
|
||||||
|
vec![#(#self),*]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dir_debug(input: pm1::TokenStream) -> pm1::TokenStream {
|
||||||
|
let path = parse_macro_input!(input as LitStr).value();
|
||||||
|
|
||||||
|
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,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue