Skip to content

Commit

Permalink
clean up parsing logic and error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
ealmloff committed Feb 22, 2024
1 parent 9ba5045 commit c5d9fed
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 54 deletions.
7 changes: 0 additions & 7 deletions macro/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ pub struct FileAssetParser {

impl Parse for FileAssetParser {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let image = input.parse::<syn::Ident>()?;
if image != "file" {
return Err(syn::Error::new(
proc_macro2::Span::call_site(),
format!("Expected file, found {}", image),
));
}
let inside;
parenthesized!(inside in input);
let path = inside.parse::<syn::LitStr>()?;
Expand Down
7 changes: 0 additions & 7 deletions macro/src/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,6 @@ pub struct FontAssetParser {

impl Parse for FontAssetParser {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let image = input.parse::<syn::Ident>()?;
if image != "font" {
return Err(syn::Error::new(
proc_macro2::Span::call_site(),
format!("Expected font, found {}", image),
));
}
let _inside;
parenthesized!(_inside in input);

Expand Down
9 changes: 1 addition & 8 deletions macro/src/image.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use manganis_common::{ FileAsset, FileOptions, FileSource, ImageOptions};
use manganis_common::{FileAsset, FileOptions, FileSource, ImageOptions};
use quote::{quote, ToTokens};
use syn::{parenthesized, parse::Parse, Token};

Expand Down Expand Up @@ -158,13 +158,6 @@ pub struct ImageAssetParser {

impl Parse for ImageAssetParser {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let image = input.parse::<syn::Ident>()?;
if image != "image" {
return Err(syn::Error::new(
proc_macro2::Span::call_site(),
format!("Expected image, found {}", image),
));
}
let inside;
parenthesized!(inside in input);
let path = inside.parse::<syn::LitStr>()?;
Expand Down
78 changes: 49 additions & 29 deletions macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use image::ImageAssetParser;
use manganis_common::{AssetType, MetadataAsset, TailwindAsset};
use proc_macro::TokenStream;
use proc_macro2::Ident;
use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, ToTokens};
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
Expand Down Expand Up @@ -116,8 +117,6 @@ pub fn classes(input: TokenStream) -> TokenStream {
/// ```
#[proc_macro]
pub fn mg(input: TokenStream) -> TokenStream {
use proc_macro2::TokenStream as TokenStream2;

let builder_tokens = {
let input = input.clone();
parse_macro_input!(input as TokenStream2)
Expand All @@ -130,37 +129,58 @@ pub fn mg(input: TokenStream) -> TokenStream {
};
};

let asset = syn::parse::<ImageAssetParser>(input.clone())
.ok()
.map(ToTokens::into_token_stream)
.or_else(|| {
syn::parse::<FontAssetParser>(input.clone())
.ok()
.map(ToTokens::into_token_stream)
let asset = parse_macro_input!(input as AnyAssetParser);

quote! {
{
#builder_output
#asset
}
}
.into_token_stream()
.into()
}

enum AnyAssetParser {
File(FileAssetParser),
Image(ImageAssetParser),
Font(FontAssetParser),
}

impl Parse for AnyAssetParser {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let ident = input.parse::<syn::Ident>()?;
let as_string = ident.to_string();

Ok(match &*as_string {
"file" => Self::File(input.parse::<FileAssetParser>()?),
"image" => Self::Image(input.parse::<ImageAssetParser>()?),
"font" => Self::Font(input.parse::<FontAssetParser>()?),
_ => {
return Err(syn::Error::new(
proc_macro2::Span::call_site(),
format!(
"Unknown asset type: {as_string}. Supported types are file, image, font"
),
))
}
})
.or_else(|| {
syn::parse::<FileAssetParser>(input.clone())
.ok()
.map(ToTokens::into_token_stream)
});

match asset {
Some(asset) => quote! {
{
#builder_output
#asset
}
}

impl ToTokens for AnyAssetParser {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
match self {
Self::File(file) => {
file.to_tokens(tokens);
}
}
.into_token_stream()
.into(),
None => quote! {
{
#builder_output
compile_error!("Expected an image, font or file asset")
Self::Image(image) => {
image.to_tokens(tokens);
}
Self::Font(font) => {
font.to_tokens(tokens);
}
}
.into_token_stream()
.into(),
}
}

Expand Down
5 changes: 2 additions & 3 deletions test-package/test-package-nested-dependency/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ pub const RESIZED_JPEG_ASSET: manganis::ImageAsset =
manganis::mg!(image("./rustacean-flat-gesture.png")
.format(ImageType::Jpg)
.size(52, 52));
pub const AVIF_ASSET: manganis::ImageAsset = manganis::mg!(image("./rustacean-flat-gesture.png")
.format(ImageType::Avif)
.low_quality_preview());
pub const AVIF_ASSET: manganis::ImageAsset =
manganis::mg!(image("./rustacean-flat-gesture.png").format(ImageType::Avif));
pub const RESIZED_AVIF_ASSET: manganis::ImageAsset =
manganis::mg!(image("./rustacean-flat-gesture.png")
.format(ImageType::Avif)
Expand Down

0 comments on commit c5d9fed

Please sign in to comment.