From a50b143f69d455daca7a85f8fc5859deeaa11256 Mon Sep 17 00:00:00 2001 From: Vlamonster Date: Wed, 17 Apr 2024 13:52:03 +0200 Subject: [PATCH 1/4] Remove `proc-macro-error` crate mentioned in issue #4. --- Cargo.toml | 7 +++---- src/lib.rs | 32 +++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f2738fa..5ae6660 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ repository = "https://github.com/binary-banter/test-each-file" proc-macro = true [dependencies] -quote = "1.0.33" -proc-macro2 = "1.0.69" -syn = { version = "2.0.39", features = ["full"] } -proc-macro-error = "1.0.4" +quote = "1.0.36" +proc-macro2 = "1.0.81" +syn = { version = "2.0.59", features = ["full"] } diff --git a/src/lib.rs b/src/lib.rs index cf6af25..9cc9354 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![doc = include_str!("../README.md")] use proc_macro2::{Ident, TokenStream}; -use proc_macro_error::{abort, abort_call_site, proc_macro_error}; use quote::{format_ident, quote}; use std::collections::{HashMap, HashSet}; use std::path::{Path, PathBuf}; @@ -15,6 +14,18 @@ struct ForEachArgs { extensions: Vec, } +macro_rules! abort { + ($span:expr, $message:expr) => { + return Err(syn::Error::new($span, $message)) + }; +} + +macro_rules! abort_token_stream { + ($span:expr, $message:expr) => { + return syn::Error::new($span, $message).into_compile_error().into() + }; +} + impl Parse for ForEachArgs { fn parse(input: ParseStream) -> syn::Result { // Optionally parse extensions if the keyword `for` is used. Aborts if none are given. @@ -79,7 +90,7 @@ struct Tree { } impl Tree { - fn new(base: &Path, ignore_extensions: bool) -> Self { + fn new(base: &Path, ignore_extensions: bool) -> Result { let mut tree = Self::default(); for entry in base.read_dir().unwrap() { let mut entry = entry.unwrap().path(); @@ -91,13 +102,13 @@ impl Tree { } else if entry.is_dir() { tree.children.insert( entry.as_path().to_path_buf(), - Self::new(entry.as_path(), ignore_extensions), + Self::new(entry.as_path(), ignore_extensions)?, ); } else { - abort_call_site!(format!("Unsupported path: {:#?}.", entry)) + return Err(format!("Unsupported path: {:#?}.", entry)); } } - tree + Ok(tree) } } @@ -166,11 +177,16 @@ fn test_each(input: proc_macro::TokenStream, invocation_type: &Type) -> proc_mac let parsed = parse_macro_input!(input as ForEachArgs); if !Path::new(&parsed.path.value()).is_dir() { - abort!(parsed.path.span(), "Given directory does not exist"); + abort_token_stream!(parsed.path.span(), "Given directory does not exist"); } let mut tokens = TokenStream::new(); - let files = Tree::new(parsed.path.value().as_ref(), !parsed.extensions.is_empty()); + + let files = match Tree::new(parsed.path.value().as_ref(), !parsed.extensions.is_empty()) { + Ok(files) => files, + Err(e) => abort_token_stream!(parsed.path.span(), e), + }; + generate_from_tree(&files, &parsed, &mut tokens, invocation_type); if let Some(module) = parsed.module { @@ -190,7 +206,6 @@ fn test_each(input: proc_macro::TokenStream, invocation_type: &Type) -> proc_mac /// /// See crate level documentation for details. #[proc_macro] -#[proc_macro_error] pub fn test_each_file(input: proc_macro::TokenStream) -> proc_macro::TokenStream { test_each(input, &Type::File) } @@ -199,7 +214,6 @@ pub fn test_each_file(input: proc_macro::TokenStream) -> proc_macro::TokenStream /// /// See crate level documentation for details. #[proc_macro] -#[proc_macro_error] pub fn test_each_path(input: proc_macro::TokenStream) -> proc_macro::TokenStream { test_each(input, &Type::Path) } From 4fca376dbeba7309f53619c70b92528fe21412f1 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 17 Apr 2024 14:05:46 +0200 Subject: [PATCH 2/4] Improve error message when files are not found --- src/lib.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9cc9354..94d8bfb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -122,7 +122,7 @@ fn generate_from_tree( parsed: &ForEachArgs, stream: &mut TokenStream, invocation_type: &Type, -) { +) -> Result<(), String> { for file in &tree.here { let file_name = format_ident!("{}", file.file_stem().unwrap().to_str().unwrap()); @@ -140,7 +140,10 @@ fn generate_from_tree( let mut arguments = TokenStream::new(); for extension in &parsed.extensions { - let input = file.with_extension(extension).canonicalize().unwrap(); + let input = match file.with_extension(extension).canonicalize() { + Ok(path) => path, + Err(e) => return Err(format!("Failed to read expected file {}.{extension}: {e}", file.display())), + }; let input = input.to_str().unwrap(); arguments.extend(match invocation_type { @@ -162,7 +165,7 @@ fn generate_from_tree( for (name, directory) in &tree.children { let mut sub_stream = TokenStream::new(); - generate_from_tree(directory, parsed, &mut sub_stream, invocation_type); + generate_from_tree(directory, parsed, &mut sub_stream, invocation_type)?; let name = format_ident!("{}", name.file_name().unwrap().to_str().unwrap()); stream.extend(quote! { mod #name { @@ -171,6 +174,8 @@ fn generate_from_tree( } }); } + + Ok(()) } fn test_each(input: proc_macro::TokenStream, invocation_type: &Type) -> proc_macro::TokenStream { @@ -187,7 +192,9 @@ fn test_each(input: proc_macro::TokenStream, invocation_type: &Type) -> proc_mac Err(e) => abort_token_stream!(parsed.path.span(), e), }; - generate_from_tree(&files, &parsed, &mut tokens, invocation_type); + if let Err(e) = generate_from_tree(&files, &parsed, &mut tokens, invocation_type) { + abort_token_stream!(parsed.path.span(), e) + } if let Some(module) = parsed.module { tokens = quote! { From 87c8c324eaec1b3917284040e2075f09eecbefe4 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 17 Apr 2024 14:16:05 +0200 Subject: [PATCH 3/4] Merge? --- src/lib.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3a01a2b..ae92e9d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -166,7 +166,7 @@ fn generate_from_tree( parsed: &TestEachArgs, stream: &mut TokenStream, invocation_type: &Type, -) { +) -> Result<(), String> { let mut taken_names_folders = HashSet::new(); for (name, directory) in tree.children.iter() { let file_name = name.file_name().unwrap().to_str().unwrap(); @@ -174,7 +174,7 @@ fn generate_from_tree( let file_name = generate_name(file_name, &mut taken_names_folders); let mut sub_stream = TokenStream::new(); - generate_from_tree(directory, parsed, &mut sub_stream, invocation_type); + generate_from_tree(directory, parsed, &mut sub_stream, invocation_type)?; stream.extend(quote! { mod #file_name { use super::*; @@ -203,10 +203,13 @@ fn generate_from_tree( let mut arguments = TokenStream::new(); for extension in &parsed.extensions { - let input = file.with_extension(extension).canonicalize().unwrap(); + let input = match file.with_extension(extension).canonicalize() { + Ok(path) => path, + Err(e) => return Err(format!("Failed to read expected file {}.{extension}: {e}", file.display())), + }; if !input.exists() { - abort_call_site!(format!( - "Expected file {:?} with extension {}, but it does not exist.", + return Err(format!( + "Expected file {:?}.{}, but it does not exist.", file, extension )) } @@ -228,6 +231,8 @@ fn generate_from_tree( } }); } + + Ok(()) } fn test_each(input: proc_macro::TokenStream, invocation_type: &Type) -> proc_macro::TokenStream { @@ -247,8 +252,6 @@ fn test_each(input: proc_macro::TokenStream, invocation_type: &Type) -> proc_mac if let Err(e) = generate_from_tree(&files, &parsed, &mut tokens, invocation_type) { abort_token_stream!(parsed.path.span(), e) } - let files = Tree::new(parsed.path.value().as_ref(), &parsed.extensions); - generate_from_tree(&files, &parsed, &mut tokens, invocation_type); if let Some(module) = parsed.module { tokens = quote! { From 1edc670bb71e558e45ac336fd7fd1f51d996d6a9 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Wed, 17 Apr 2024 14:17:36 +0200 Subject: [PATCH 4/4] Remove redundant error check --- src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ae92e9d..f9cd591 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -207,12 +207,6 @@ fn generate_from_tree( Ok(path) => path, Err(e) => return Err(format!("Failed to read expected file {}.{extension}: {e}", file.display())), }; - if !input.exists() { - return Err(format!( - "Expected file {:?}.{}, but it does not exist.", - file, extension - )) - } let input = input.to_str().unwrap(); arguments.extend(match invocation_type {