From 62f8d1522ef719c95bca612336d479a3df451cf3 Mon Sep 17 00:00:00 2001 From: Guillaume Binet Date: Sat, 18 May 2024 09:43:34 -0400 Subject: [PATCH] move the ugliness out of the way. --- copper_derive/src/lib.rs | 56 ++++++++------------------------------ copper_derive/src/utils.rs | 39 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 45 deletions(-) create mode 100644 copper_derive/src/utils.rs diff --git a/copper_derive/src/lib.rs b/copper_derive/src/lib.rs index f5f0621a5..29d9485ba 100644 --- a/copper_derive/src/lib.rs +++ b/copper_derive/src/lib.rs @@ -1,18 +1,15 @@ extern crate proc_macro; +use copper::config::CopperConfig; +use format::{highlight_rust_code, rustfmt_generated_code}; use proc_macro::TokenStream; -use std::path::PathBuf; - use quote::quote; -use syn::{Field, ItemStruct, LitStr, parse_macro_input, parse_quote}; -use syn::Fields::{Named, Unit, Unnamed}; use syn::meta::parser; -use walkdir::WalkDir; - -use copper::config::CopperConfig; -use format::{highlight_rust_code, rustfmt_generated_code}; +use syn::Fields::{Named, Unit, Unnamed}; +use syn::{parse_macro_input, parse_quote, Field, ItemStruct, LitStr}; mod format; +mod utils; // Parses the CopperRuntime attribute like #[copper_runtime(config = "path")] #[proc_macro_attribute] @@ -30,10 +27,13 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream { }); parse_macro_input!(args with attribute_config_parser); - let config_file = config_file.expect("Expected config file attribute like #[CopperRuntime(config = \"path\")]").value(); - let mut config_full_path = caller_crate_root(); + let config_file = config_file + .expect("Expected config file attribute like #[CopperRuntime(config = \"path\")]") + .value(); + let mut config_full_path = utils::caller_crate_root(); config_full_path.push(config_file); - let config_content = std::fs::read_to_string(&config_full_path).unwrap_or_else(|_| panic!("Failed to read configuration file: {:?}", &config_full_path)); + let config_content = std::fs::read_to_string(&config_full_path) + .unwrap_or_else(|_| panic!("Failed to read configuration file: {:?}", &config_full_path)); println!("Config content:\n {}", config_content); let deserialized = CopperConfig::deserialize(&config_content); @@ -76,37 +76,3 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream { tokens } - -// Lifted this HORROR but it works. -fn caller_crate_root() -> PathBuf { - let crate_name = - std::env::var("CARGO_PKG_NAME").expect("failed to read ENV var `CARGO_PKG_NAME`!"); - let current_dir = std::env::current_dir().expect("failed to unwrap env::current_dir()!"); - let search_entry = format!("name=\"{crate_name}\""); - for entry in WalkDir::new(¤t_dir) - .into_iter() - .filter_entry(|e| !e.file_name().eq_ignore_ascii_case("target")) - { - let Ok(entry) = entry else { continue; }; - if !entry.file_type().is_file() { - continue; - } - let Some(file_name) = entry.path().file_name() else { continue; }; - if !file_name.eq_ignore_ascii_case("Cargo.toml") { - continue; - } - let Ok(cargo_toml) = std::fs::read_to_string(entry.path()) else { - continue; - }; - if cargo_toml - .chars() - .filter(|&c| !c.is_whitespace()) - .collect::() - .contains(search_entry.as_str()) - { - return entry.path().parent().unwrap().to_path_buf(); - } - } - current_dir -} - diff --git a/copper_derive/src/utils.rs b/copper_derive/src/utils.rs new file mode 100644 index 000000000..5b140f7b5 --- /dev/null +++ b/copper_derive/src/utils.rs @@ -0,0 +1,39 @@ +use std::path::PathBuf; +use walkdir::WalkDir; + +// Lifted this HORROR but it works. +pub fn caller_crate_root() -> PathBuf { + let crate_name = + std::env::var("CARGO_PKG_NAME").expect("failed to read ENV var `CARGO_PKG_NAME`!"); + let current_dir = std::env::current_dir().expect("failed to unwrap env::current_dir()!"); + let search_entry = format!("name=\"{crate_name}\""); + for entry in WalkDir::new(¤t_dir) + .into_iter() + .filter_entry(|e| !e.file_name().eq_ignore_ascii_case("target")) + { + let Ok(entry) = entry else { + continue; + }; + if !entry.file_type().is_file() { + continue; + } + let Some(file_name) = entry.path().file_name() else { + continue; + }; + if !file_name.eq_ignore_ascii_case("Cargo.toml") { + continue; + } + let Ok(cargo_toml) = std::fs::read_to_string(entry.path()) else { + continue; + }; + if cargo_toml + .chars() + .filter(|&c| !c.is_whitespace()) + .collect::() + .contains(search_entry.as_str()) + { + return entry.path().parent().unwrap().to_path_buf(); + } + } + current_dir +}