From 1ef05ec04d811ce5c491a6f442eb091bdb2f0c6e Mon Sep 17 00:00:00 2001 From: Mario Carbajal Date: Thu, 11 Jan 2024 14:23:04 -0300 Subject: [PATCH] Report errors using syn::Error --- Cargo.lock | 1 + internal/stylance-macros/Cargo.toml | 1 + internal/stylance-macros/src/lib.rs | 85 ++++++++++++++++------------- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 436032b..6e38060 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -387,6 +387,7 @@ dependencies = [ name = "stylance-macros" version = "0.0.7" dependencies = [ + "anyhow", "proc-macro2", "quote", "stylance-core", diff --git a/internal/stylance-macros/Cargo.toml b/internal/stylance-macros/Cargo.toml index ef11cd4..589a375 100644 --- a/internal/stylance-macros/Cargo.toml +++ b/internal/stylance-macros/Cargo.toml @@ -14,6 +14,7 @@ nightly = [] [dependencies] stylance-core = { workspace = true } +anyhow = "1.0.79" proc-macro2 = "1.0.71" quote = "1.0.33" syn = { version = "2.0.43", features = ["extra-traits"] } diff --git a/internal/stylance-macros/src/lib.rs b/internal/stylance-macros/src/lib.rs index c56c608..64a1b61 100644 --- a/internal/stylance-macros/src/lib.rs +++ b/internal/stylance-macros/src/lib.rs @@ -2,20 +2,17 @@ use std::{env, path::Path}; +use anyhow::Context as _; use proc_macro::TokenStream; use proc_macro2::{Ident, Span}; use quote::quote; use syn::{parse_macro_input, LitStr}; -#[proc_macro] -pub fn import_style_classes(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as LitStr); - - let manifest_dir_env = env::var_os("CARGO_MANIFEST_DIR").expect("we need CARGO_MANIFEST_DIR"); - let manifest_path = Path::new(&manifest_dir_env); - let file_path = manifest_path.join(Path::new(&input.value())); - - let (_, classes) = stylance_core::get_classes(manifest_path, &file_path).expect("Load classes"); +fn try_import_style_classes_with_path( + manifest_path: &Path, + file_path: &Path, +) -> anyhow::Result { + let (_, classes) = stylance_core::get_classes(manifest_path, &file_path)?; let binding = file_path.canonicalize().unwrap(); let full_path = binding.to_string_lossy(); @@ -33,19 +30,38 @@ pub fn import_style_classes(input: TokenStream) -> TokenStream { } }); - quote! { + Ok(quote! { const _ : &[u8] = include_bytes!(#full_path); #(#output_fields )* } - .into() + .into()) +} + +fn try_import_style_classes(input: &LitStr) -> anyhow::Result { + let manifest_dir_env = + env::var_os("CARGO_MANIFEST_DIR").context("CARGO_MANIFEST_DIR env var not found")?; + let manifest_path = Path::new(&manifest_dir_env); + let file_path = manifest_path.join(Path::new(&input.value())); + + try_import_style_classes_with_path(manifest_path, &file_path) +} + +#[proc_macro] +pub fn import_style_classes(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as LitStr); + + match try_import_style_classes(&input) { + Ok(ts) => ts, + Err(err) => syn::Error::new_spanned(&input, err.to_string()) + .to_compile_error() + .into(), + } } #[cfg(feature = "nightly")] -#[proc_macro] -pub fn import_style_classes_rel(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as LitStr); - - let manifest_dir_env = env::var_os("CARGO_MANIFEST_DIR").expect("we need CARGO_MANIFEST_DIR"); +fn try_import_style_classes_rel(input: &LitStr) -> anyhow::Result { + let manifest_dir_env = + env::var_os("CARGO_MANIFEST_DIR").context("CARGO_MANIFEST_DIR env var not found")?; let manifest_path = Path::new(&manifest_dir_env); let call_site_path = proc_macro::Span::call_site().source().source_file().path(); @@ -54,27 +70,18 @@ pub fn import_style_classes_rel(input: TokenStream) -> TokenStream { .expect("No current path") .join(input.value()); - let (_, classes) = stylance_core::get_classes(manifest_path, &file_path).expect("Load classes"); - - let binding = file_path.canonicalize().unwrap(); - let full_path = binding.to_string_lossy(); - - let identifiers = classes - .iter() - .map(|class| Ident::new(&class.original_name.replace('-', "_"), Span::call_site())) - .collect::>(); - - let output_fields = classes.iter().zip(identifiers).map(|(class, class_ident)| { - let class_str = &class.hashed_name; - quote! { - #[allow(non_upper_case_globals)] - pub const #class_ident: &str = #class_str; - } - }); - - quote! { - const _ : &[u8] = include_bytes!(#full_path); - #(#output_fields )* - } - .into() + try_import_style_classes_with_path(manifest_path, &file_path) +} + +#[cfg(feature = "nightly")] +#[proc_macro] +pub fn import_style_classes_rel(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as LitStr); + + match try_import_style_classes_rel(&input) { + Ok(ts) => ts, + Err(err) => syn::Error::new_spanned(&input, err.to_string()) + .to_compile_error() + .into(), + } }