Skip to content

Commit

Permalink
Make code DRYer; rearrange the modules
Browse files Browse the repository at this point in the history
  • Loading branch information
DanikVitek committed Jan 20, 2025
1 parent 420a69b commit 166ef4b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 53 deletions.
6 changes: 3 additions & 3 deletions macros/src/async_generic_target/fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn transform(
AsyncGenericFn::<kind::Async, _>::new(target_fn, async_signature).rewrite(),
)
}

transform(target_fn.into(), async_signature)
}

Expand Down Expand Up @@ -135,9 +135,9 @@ impl Parse for TargetItemFn {
InspectExt::inspect(fork.parse().map(TargetItemFn::Impl), |_| {
input.advance_to(&fork)
})
.or_else(|err3| {
.map_err(|err3| {
err1.extend([err2, err3]);
Err(err1)
err1
})
})
})?
Expand Down
43 changes: 11 additions & 32 deletions macros/src/async_generic_target/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use proc_macro2::Span;
use syn::{
parse::{discouraged::Speculative, Parse, ParseStream},
punctuated::Punctuated,
Error, ItemImpl, ItemTrait, Meta, Result, Token,
Error, Result,
};

use self::r#fn::TargetItemFn;
use self::{r#fn::TargetItemFn, trait_part::TargetTraitPart};

pub mod r#fn;
pub mod trait_part;
Expand All @@ -17,8 +16,7 @@ pub mod state {

pub enum TargetItem {
Fn(TargetItemFn),
Trait(ItemTrait),
Impl(ItemImpl),
TraitPart(TargetTraitPart),
}

impl Parse for TargetItem {
Expand All @@ -32,39 +30,20 @@ impl Parse for TargetItem {
})
.or_else(|err1| {
let fork = input.fork();
InspectExt::inspect(fork.parse().map(TargetItem::Trait), |_| {
InspectExt::inspect(fork.parse().map(TargetItem::TraitPart), |_| {
input.advance_to(&fork)
})
.or_else(|err2| {
let fork = input.fork();
InspectExt::inspect(fork.parse().map(TargetItem::Impl), |_| {
input.advance_to(&fork)
})
.map_err(|err3| {
let mut err = Error::new(
Span::call_site(),
"async_generic can only be used with functions, traits or impls",
);
err.extend([err1, err2, err3]);
err
})
.map_err(|err2| {
let mut err = Error::new(
Span::call_site(),
"async_generic can only be used with functions, traits or impls",
);
err.extend([err1, err2]);
err
})
})?
};

Ok(target_item)
}
}

#[derive(Default)]
pub struct LaterAttributes {
attrs: Punctuated<Meta, Token![,]>,
}

impl Parse for LaterAttributes {
fn parse(input: ParseStream) -> Result<Self> {
Ok(Self {
attrs: Punctuated::parse_terminated(input)?,
})
}
}
68 changes: 61 additions & 7 deletions macros/src/async_generic_target/trait_part/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,75 @@ use core::marker::PhantomData;

use proc_macro2::TokenStream as TokenStream2;
use quote::ToTokens;
use syn::{parse2, AttrStyle, Attribute, Meta, MetaList};
use syn::{
parse::{discouraged::Speculative, Parse, ParseStream},
parse2,
punctuated::Punctuated,
AttrStyle, Attribute, ItemImpl, ItemTrait, Meta, MetaList, Token,
};

use super::{
r#fn::{AsyncGenericFn, TargetItemFn},
state, LaterAttributes,
state,
};

pub mod r#impl;
pub mod r#trait;

pub fn expand<T: TraitPart>(target: T, later_attributes: LaterAttributes) -> TokenStream2 {
AsyncGenericTraitPart::<T, _>::new(target, later_attributes)
.rewrite()
.map(|r#trait| r#trait.into_token_stream())
.unwrap_or_else(|err| err.into_compile_error())
pub fn expand(target: TargetTraitPart, later_attributes: LaterAttributes) -> TokenStream2 {
fn expand<T: TraitPart>(target: T, later_attributes: LaterAttributes) -> TokenStream2 {
AsyncGenericTraitPart::new(target, later_attributes)
.rewrite()
.map(|r#trait| r#trait.into_token_stream())
.unwrap_or_else(|err| err.into_compile_error())
}
match target {
TargetTraitPart::Trait(item) => expand(item, later_attributes),
TargetTraitPart::Impl(item) => expand(item, later_attributes),
}
}

pub enum TargetTraitPart {
Trait(ItemTrait),
Impl(ItemImpl),
}

impl Parse for TargetTraitPart {
fn parse(input: ParseStream) -> syn::Result<Self> {
let target_item = {
use crate::util::InspectExt;

let fork = input.fork();
InspectExt::inspect(fork.parse().map(TargetTraitPart::Trait), |_| {
input.advance_to(&fork)
})
.or_else(|mut err1| {
let fork = input.fork();
InspectExt::inspect(fork.parse().map(TargetTraitPart::Impl), |_| {
input.advance_to(&fork)
})
.map_err(|err2| {
err1.extend(Some(err2));
err1
})
})?
};

Ok(target_item)
}
}

#[derive(Default)]
pub struct LaterAttributes {
attrs: Punctuated<Meta, Token![,]>,
}

impl Parse for LaterAttributes {
fn parse(input: ParseStream) -> syn::Result<Self> {
Ok(Self {
attrs: Punctuated::parse_terminated(input)?,
})
}
}

pub trait TraitPart: ToTokens {
Expand Down
14 changes: 3 additions & 11 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use proc_macro::TokenStream;
use syn::parse_macro_input;

use crate::async_generic_target::{r#fn::AsyncSignature, LaterAttributes, TargetItem};
use self::async_generic_target::{r#fn::AsyncSignature, trait_part::LaterAttributes, TargetItem};

mod async_generic_target;
mod util;
Expand All @@ -22,21 +22,13 @@ pub fn async_generic(args: TokenStream, input: TokenStream) -> TokenStream {
};
async_generic_target::r#fn::expand(target_fn, async_signature).into()
}
target_item @ (TargetItem::Trait(_) | TargetItem::Impl(_)) => {
TargetItem::TraitPart(target_trait_part) => {
let later_attributes = if args.is_empty() {
LaterAttributes::default()
} else {
parse_macro_input!(args as LaterAttributes)
};
match target_item {
TargetItem::Trait(item) => {
async_generic_target::trait_part::expand(item, later_attributes).into()
}
TargetItem::Impl(item) => {
async_generic_target::trait_part::expand(item, later_attributes).into()
}
_ => unreachable!(),
}
async_generic_target::trait_part::expand(target_trait_part, later_attributes).into()
}
}
}

0 comments on commit 166ef4b

Please sign in to comment.