Something went wrong. Try again.
This string has no description
Something went wrong. Try again.
3.9 kB · 132 lines · Created 4mo ago Rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133#![cfg_attr(not(test), no_std)]#![feature(fn_traits)]#![feature(unboxed_closures)]
pub use paste::paste;
#[macro_export]macro_rules! fn_to_struct { () => {}; ($vi:vis fn $name:ident<$($life:lifetime,)* $($t:ident $(: $bound:path)?),*>($($arg:ident: $argt:ty),*) -> $ret:ty $(where $($wlife:lifetime),* $($wt:ident $(: $wbound:path)?,)*)? $body:block $($rem:tt)*) => { #[allow(non_camel_case_types)] #[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)] $vi enum $name<$($life,)* $($t $(: $bound)?,)*> $(where $($wlife,)* $($wt $(: $wbound)?,)*)? { __Generics(::core::marker::PhantomData<($(&$life (),)* $($t,)*)>), $name, }
$crate::paste! { mod [<__ $name>] { pub(super) use super::$name::$name; }
#[allow(unused_imports)] $vi use [<__ $name>]::*; }
impl<$($life,)* $($t $(: $bound)?,)*> Default for $name<$($life,)* $($t,)*> $(where $($wlife,)* $($wt $(: $wbound)?,)*)? { fn default() -> Self { Self::$name } }
impl<$($life,)* $($t $(: $bound)?,)*> ::core::ops::FnOnce<($($argt,)*)> for $name<$($life,)* $($t,)*> $(where $($wlife,)* $($wt $(: $wbound)?,)*)? { type Output = $ret;
extern "rust-call" fn call_once(self, ($($arg,)*): ($($argt,)*)) -> Self::Output { $body } }
impl<$($life,)* $($t $(: $bound)?,)*> ::core::ops::FnMut<($($argt,)*)> for $name<$($life,)* $($t,)*> $(where $($wlife,)* $($wt $(: $wbound)?,)*)? { extern "rust-call" fn call_mut(&mut self, ($($arg,)*): ($($argt,)*)) -> Self::Output { $body } }
impl<$($life,)* $($t $(: $bound)?,)*> ::core::ops::Fn<($($argt,)*)> for $name<$($life,)* $($t,)*> $(where $($wlife,)* $($wt $(: $wbound)?,)*)? { extern "rust-call" fn call(&self, ($($arg,)*): ($($argt,)*)) -> Self::Output { $body } }
$crate::fn_to_struct! { $($rem)* } }; ($vi:vis fn $name:ident<$($life:lifetime),*> $($rem:tt)*) => { $crate::fn_to_struct!($vi fn $name<$($life,)*> $($rem)*) }; ($vi:vis fn $name:ident($($arg:ident: $argt:ty),*) -> $ret:ty $body:block $($rem:tt)*) => { #[allow(non_camel_case_types)] #[derive(PartialEq, Eq, Clone, Copy, Hash, Default, Debug)] $vi struct $name;
impl ::core::ops::FnOnce<($($argt,)*)> for $name { type Output = $ret;
extern "rust-call" fn call_once(self, ($($arg,)*): ($($argt,)*)) -> Self::Output { $body } }
impl ::core::ops::FnMut<($($argt,)*)> for $name { extern "rust-call" fn call_mut(&mut self, ($($arg,)*): ($($argt,)*)) -> Self::Output { $body } }
impl ::core::ops::Fn<($($argt,)*)> for $name { extern "rust-call" fn call(&self, ($($arg,)*): ($($argt,)*)) -> Self::Output { $body } }
$crate::fn_to_struct! { $($rem)* } }; ($vi:vis fn $name:ident($($arg:ident: $argt:ty),*) $body:block $($rem:tt)*) => { $crate::fn_to_struct! { $vi fn $name($($arg: $argt),*) -> () $body $($rem)* } };}
#[cfg(test)]fn_to_struct!( fn test() {} fn test2(a: u32) -> u32 { a + 42 } pub fn test3(a: u32, b: u32) -> u32 { a + b } pub fn test4() -> test3 { test3 } fn test5<'a, A>(a: A) -> A where A: Sized, { a });
#[test]#[cfg(test)]fn test_functions() { assert_eq!((), test()); assert_eq!(42, test2(0)); assert_eq!(90, test3(30, 60)); assert_eq!(132, test4()(42, 90)); assert_eq!(132, test5::<u32>(132));}