#![feature(let_else)]
#![feature(proc_macro_span)]
#![doc(html_root_url = "https://docs.rs/list_files_macro/0.1.0")]
use glob::glob;
use proc_macro::{TokenStream, Span};
use syn::{Expr, punctuated::Punctuated, Token, parse::Parser, ExprLit, Lit, ExprPath};
use quote::quote;
#[proc_macro]
pub fn list_files(input: TokenStream) -> TokenStream {
let parser = Punctuated::<Expr, Token![,]>::parse_separated_nonempty;
let args = parser.parse(input).unwrap().into_iter().collect::<Vec<_>>();
let (path, handler) = match &args[..] {
[
Expr::Path(ExprPath { path: handler, .. }),
Expr::Lit(ExprLit { lit: Lit::Str(path), .. }),
] => (path.value(), Some(handler)),
[Expr::Lit(ExprLit { lit: Lit::Str(path), .. })] => (path.value(), None),
_ => panic!("Usage: list_files!(\"path/to/dir\") | list_files!(handler_macro, \"path/to/dir\")"),
};
let absolute_path =
if path.starts_with(".") {
let source_path = Span::call_site().source_file().path();
source_path.parent().unwrap().join(&path).into_os_string().into_string().unwrap()
} else {
path
};
let files = glob(&absolute_path).unwrap();
let file_literals = files.map(|file| {
let file = file.unwrap().canonicalize().unwrap().into_os_string().into_string().unwrap();
quote!(#file)
});
if let Some(handler) = handler {
quote!([#(#handler!(#file_literals)),*])
} else {
quote!([#(#file_literals),*])
}.into()
}
#[doc = include_str!("../README.md")]
#[doc = include_str!("../CHANGELOG.md")]
type _Doctest = ();