Skip to content

Commit

Permalink
Add support for generic types to easy_wrapper (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
notgull committed May 17, 2023
1 parent 6d2a097 commit fb90f08
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 4 deletions.
84 changes: 80 additions & 4 deletions strategy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,75 @@ pub use pin_project_lite::pin_project;
macro_rules! easy_wrapper {
(
$(#[$meta:meta])*
$vis:vis struct $name:ident ($inner:ty => $output:ty);
$vis:vis struct $name:ident

$(<
$( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
$( $generics:ident
$(: $generics_bound:path)?
$(: ?$generics_unsized_bound:path)?
$(: $generics_lifetime_bound:lifetime)?
$(= $generics_default:ty)?
),* $(,)?
>)?

($inner:ty => $output:ty)

$(where
$( $where_clause_ty:ty
$(: $where_clause_bound:path)?
$(: ?$where_clause_unsized_bound:path)?
$(: $where_clause_lifetime_bound:lifetime)?
),* $(,)?
)?

;

$(#[$wait_meta:meta])*
$wait_vis: vis wait();
) => {
$crate::pin_project! {
$(#[$meta])*
$vis struct $name {
$vis struct $name $(<
$( $lifetime $(: $lifetime_bound)? ),*
$( $generics
$(: $generics_bound)?
$(: ?$generics_unsized_bound)?
$(: $generics_lifetime_bound)?
$(= $generics_default)?
),*
>)? $(
where
$( $where_clause_ty
$(: $where_clause_bound)?
$(: ?$where_clause_unsized_bound)?
$(: $where_clause_lifetime_bound)?
),*
)? {
#[pin]
_inner: $crate::FutureWrapper<$inner>
}
}

impl $name {
impl $(<
$( $lifetime $(: $lifetime_bound)? ,)*
$( $generics
$(: $generics_bound)?
$(: ?$generics_unsized_bound)?
$(: $generics_lifetime_bound)?
$(= $generics_default)?
),*
>)? $name $(<
$( $lifetime ,)*
$( $generics ),*
>)? $(
where
$( $where_clause_ty
$(: $where_clause_bound)?
$(: ?$where_clause_unsized_bound)?
$(: $where_clause_lifetime_bound)?
),*
)? {
#[inline]
fn _new(inner: $inner) -> Self {
Self {
Expand All @@ -158,7 +214,27 @@ macro_rules! easy_wrapper {
}
}

impl ::core::future::Future for $name {
impl $(<
$( $lifetime $(: $lifetime_bound)? ,)*
$( $generics
$(: $generics_bound)?
$(: ?$generics_unsized_bound)?
$(: $generics_lifetime_bound)?
$(= $generics_default)?
),*
>)? ::core::future::Future for $name $(
<
$( $lifetime ,)*
$( $generics ),*
>
)? $(
where
$( $where_clause_ty
$(: $where_clause_bound)?
$(: ?$where_clause_unsized_bound)?
$(: $where_clause_lifetime_bound)?
),*
)? {
type Output = $output;

#[inline]
Expand Down
102 changes: 102 additions & 0 deletions strategy/tests/easy_wrapper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//! Testing of the `easy_wrapper!` macro.

use std::{marker::PhantomData, pin::Pin, task::Poll};

use event_listener_strategy::{easy_wrapper, EventListenerFuture, Strategy};

#[test]
fn easy_wrapper_generics() {
// Easy case.
struct MyStrategy;

impl EventListenerFuture for MyStrategy {
type Output = ();

fn poll_with_strategy<'a, S: Strategy<'a>>(
self: Pin<&'a mut Self>,
_strategy: &mut S,
_context: &mut S::Context,
) -> Poll<Self::Output> {
Poll::Ready(())
}
}

easy_wrapper! {
struct MyEasyWrapper(MyStrategy => ());
wait();
}

MyEasyWrapper::_new(MyStrategy).wait();

// Medium case with generics.
struct MyStrategy2<T> {
_marker: PhantomData<T>,
}

impl<T> EventListenerFuture for MyStrategy2<T> {
type Output = T;

fn poll_with_strategy<'a, S: Strategy<'a>>(
self: Pin<&'a mut Self>,
_strategy: &mut S,
_context: &mut S::Context,
) -> Poll<Self::Output> {
unreachable!()
}
}

easy_wrapper! {
struct MyEasyWrapper2<T>(MyStrategy2<T> => T);
wait();
}

// Medium mode with lifetime.
struct MyStrategylt<'a> {
_marker: PhantomData<&'a ()>,
}

impl<'a> EventListenerFuture for MyStrategylt<'a> {
type Output = &'a ();

fn poll_with_strategy<'b, S: Strategy<'b>>(
self: Pin<&'b mut Self>,
_strategy: &mut S,
_context: &mut S::Context,
) -> Poll<Self::Output> {
unreachable!()
}
}

easy_wrapper! {
struct MyEasyWrapperlt<'a>(MyStrategylt<'a> => &'a ());
wait();
}

// Hard mode with generic bounds.
struct MyStrategy3<'a, T: ?Sized>
where
T: 'a,
{
_marker: PhantomData<&'a T>,
}

impl<'a, T: ?Sized> EventListenerFuture for MyStrategy3<'a, T>
where
T: 'a,
{
type Output = &'a T;

fn poll_with_strategy<'b, S: Strategy<'b>>(
self: Pin<&'b mut Self>,
_strategy: &mut S,
_context: &mut S::Context,
) -> Poll<Self::Output> {
unreachable!()
}
}

easy_wrapper! {
struct MyEasyWrapper3<'a, T: ?Sized>(MyStrategy3<'a, T> => &'a T) where T: 'a;
wait();
}
}

0 comments on commit fb90f08

Please sign in to comment.