Report errors using syn::Error

This commit is contained in:
Mario Carbajal 2024-01-11 14:23:04 -03:00
parent b905a32c4a
commit 1ef05ec04d
3 changed files with 48 additions and 39 deletions

1
Cargo.lock generated
View File

@ -387,6 +387,7 @@ dependencies = [
name = "stylance-macros"
version = "0.0.7"
dependencies = [
"anyhow",
"proc-macro2",
"quote",
"stylance-core",

View File

@ -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"] }

View File

@ -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<TokenStream> {
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<TokenStream> {
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<TokenStream> {
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::<Vec<_>>();
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;
try_import_style_classes_with_path(manifest_path, &file_path)
}
});
quote! {
const _ : &[u8] = include_bytes!(#full_path);
#(#output_fields )*
#[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(),
}
.into()
}