#![doc(html_root_url = "https://docs.rs/serde_closure/0.3.3")]
#![cfg_attr(nightly, feature(unboxed_closures, fn_traits, tuple_trait))]
#![warn(
missing_copy_implementations,
missing_debug_implementations,
missing_docs,
trivial_casts,
trivial_numeric_casts,
unused_import_braces,
unused_qualifications,
unused_results,
clippy::pedantic
)] #![allow(clippy::inline_always)]
pub use serde_closure_derive::FnOnce;
pub use serde_closure_derive::FnMut;
pub use serde_closure_derive::Fn;
pub use serde_closure_derive::desugar;
#[doc(hidden)]
#[macro_export]
macro_rules! FnMutNamed {
(pub type $name:ident<$($t:ident),*> = |$self:ident $(,$env:ident: $env_type:ty)*|$($arg:pat=> $arg_type:ty),*| -> $output:ty where $($bound_ty:ident : $bound_trait:tt),* $body:block) => (
FnMutNamed!{ pub type $name<$($t),*> = |$self $(,$env: $env_type)*|$($arg => $arg_type),*| -> $output where $($bound_ty : $bound_trait),* ; where $body}
);
(pub type $name:ident<$($t:ident),*> = |$self:ident $(,$env:ident: $env_type:ty)*|$($arg:pat=> $arg_type:ty),*| -> $output:ty where $($bound_ty:ident : $bound_trait:tt),* ; where $($fn_bound_ty:ident : $fn_bound_trait:tt),* $body:block) => (
pub struct $name<$($t),*>
where
$($bound_ty: $bound_trait),*
{
$($env: $env_type,)*
marker: $crate::internal::core::marker::PhantomData<fn() -> ($($t,)*)>,
}
const _: () = {
impl<$($t),*> $name<$($t),*>
where
$($bound_ty: $bound_trait),*
{
#[allow(clippy::inline_always, clippy::new_without_default)]
#[inline(always)]
pub fn new($($env: $env_type),*) -> Self {
Self {
$($env: $env,)*
marker: $crate::internal::core::marker::PhantomData,
}
}
#[inline]
fn run(&mut $self, ($($arg,)*): ($($arg_type,)*)) -> $output
where
$($fn_bound_ty: $fn_bound_trait),*
$body
}
impl<$($t),*> Clone for $name<$($t),*>
where
$($bound_ty: $bound_trait,)*
$($env_type: Clone,)*
{
#[inline]
fn clone(&self) -> Self {
Self {
$($env: self.$env.clone(),)*
marker: $crate::internal::core::marker::PhantomData,
}
}
}
impl<$($t),*> $crate::internal::serde::Serialize for $name<$($t),*>
where
$($bound_ty: $bound_trait,)*
$($env_type: $crate::internal::serde::Serialize,)*
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: $crate::internal::serde::Serializer {
$crate::internal::serde::Serialize::serialize(&($(&self.$env,)*), serializer)
}
}
impl<'de, $($t),*> $crate::internal::serde::Deserialize<'de> for $name<$($t),*>
where
$($bound_ty: $bound_trait,)*
$($env_type: $crate::internal::serde::Deserialize<'de>,)*
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: $crate::internal::serde::Deserializer<'de> {
<($($env_type,)*) as $crate::internal::serde::Deserialize>::deserialize(deserializer).map(|($($env,)*)| {
Self {
$($env,)*
marker: $crate::internal::core::marker::PhantomData
}
})
}
}
#[$crate::desugar]
impl<$($t),*> $crate::traits::FnOnce($($arg_type,)*) -> $output for $name<$($t),*>
where
$($bound_ty: $bound_trait),*
$($fn_bound_ty: $fn_bound_trait),*
{
#[allow(clippy::inline_always)]
#[inline(always)]
fn call_once(mut self, args: ($($arg_type,)*)) -> Self::Output {
self.run(args)
}
}
#[$crate::desugar]
impl<$($t),*> $crate::traits::FnMut($($arg_type,)*) -> $output for $name<$($t),*>
where
$($bound_ty: $bound_trait),*
$($fn_bound_ty: $fn_bound_trait),*
{
#[allow(clippy::inline_always)]
#[inline(always)]
fn call_mut(&mut self, args: ($($arg_type,)*)) -> Self::Output {
$crate::internal::transmute(self.run(args))
}
}
};
)
}
#[doc(hidden)]
#[macro_export]
macro_rules! FnNamed {
(pub type $name:ident<$($t:ident),*> = |$self:ident $(,$env:ident: $env_type:ty)*|$($arg:pat=> $arg_type:ty),*| -> $output:ty where $($bound_ty:ident : $bound_trait:tt),* $body:block) => (
FnNamed!{ pub type $name<$($t),*> = |$self $(,$env: $env_type)*|$($arg => $arg_type),*| -> $output where $($bound_ty : $bound_trait),* ; where $body}
);
(pub type $name:ident<$($t:ident),*> = |$self:ident $(,$env:ident: $env_type:ty)*|$($arg:pat=> $arg_type:ty),*| -> $output:ty where $($bound_ty:ident : $bound_trait:tt),* ; where $($fn_bound_ty:ident : $fn_bound_trait:tt),* $body:block) => (
pub struct $name<$($t),*>
where
$($bound_ty: $bound_trait),*
{
$($env: $env_type,)*
marker: $crate::internal::core::marker::PhantomData<fn() -> ($($t,)*)>,
}
const _: () = {
impl<$($t),*> $name<$($t),*>
where
$($bound_ty: $bound_trait),*
{
#[allow(clippy::inline_always, clippy::new_without_default)]
#[inline(always)]
pub fn new($($env: $env_type),*) -> Self {
Self {
$($env: $env,)*
marker: $crate::internal::core::marker::PhantomData,
}
}
#[inline]
fn run(&$self, ($($arg,)*): ($($arg_type,)*)) -> $output
where
$($fn_bound_ty: $fn_bound_trait),*
$body
}
impl<$($t),*> Clone for $name<$($t),*>
where
$($bound_ty: $bound_trait,)*
$($env_type: Clone,)*
{
#[inline]
fn clone(&self) -> Self {
Self {
$($env: self.$env.clone(),)*
marker: $crate::internal::core::marker::PhantomData,
}
}
}
impl<$($t),*> $crate::internal::serde::Serialize for $name<$($t),*>
where
$($bound_ty: $bound_trait,)*
$($env_type: $crate::internal::serde::Serialize,)*
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: $crate::internal::serde::Serializer {
$crate::internal::serde::Serialize::serialize(&($(&self.$env,)*), serializer)
}
}
impl<'de, $($t),*> $crate::internal::serde::Deserialize<'de> for $name<$($t),*>
where
$($bound_ty: $bound_trait,)*
$($env_type: $crate::internal::serde::Deserialize<'de>,)*
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: $crate::internal::serde::Deserializer<'de> {
<($($env_type,)*) as $crate::internal::serde::Deserialize>::deserialize(deserializer).map(|($($env,)*)| {
Self {
$($env,)*
marker: $crate::internal::core::marker::PhantomData
}
})
}
}
#[$crate::desugar]
impl<$($t),*> $crate::traits::FnOnce($($arg_type,)*) -> $output for $name<$($t),*>
where
$($bound_ty: $bound_trait),*
$($fn_bound_ty: $fn_bound_trait),*
{
#[allow(clippy::inline_always)]
#[inline(always)]
fn call_once(self, args: ($($arg_type,)*)) -> Self::Output {
self.run(args)
}
}
#[$crate::desugar]
impl<$($t),*> $crate::traits::FnMut($($arg_type,)*) -> $output for $name<$($t),*>
where
$($bound_ty: $bound_trait),*
$($fn_bound_ty: $fn_bound_trait),*
{
#[allow(clippy::inline_always)]
#[inline(always)]
fn call_mut(&mut self, args: ($($arg_type,)*)) -> Self::Output {
$crate::internal::transmute(self.run(args))
}
}
#[$crate::desugar]
impl<$($t),*> $crate::traits::Fn($($arg_type,)*) -> $output for $name<$($t),*>
where
$($bound_ty: $bound_trait),*
$($fn_bound_ty: $fn_bound_trait),*
{
#[allow(clippy::inline_always)]
#[inline(always)]
fn call(&self, args: ($($arg_type,)*)) -> Self::Output {
$crate::internal::transmute(self.run(args))
}
}
};
)
}
#[doc(hidden)]
pub mod internal {
pub use core;
pub use serde;
pub use std;
use std::marker::PhantomData;
pub trait FnOnce<Args> {
type Output;
fn call_once(self, args: Args) -> Self::Output;
}
pub trait FnMut<Args>: FnOnce<Args> {
fn call_mut(&mut self, args: Args) -> Self::Output;
}
pub trait Fn<Args>: FnMut<Args> {
fn call(&self, args: Args) -> Self::Output;
}
#[inline(always)]
pub fn to_phantom<T>(_t: &T) -> PhantomData<fn(T)> {
PhantomData
}
#[inline(always)]
pub fn is_phantom<T>(_t: &T, _marker: PhantomData<fn(T)>) {}
#[allow(missing_copy_implementations, missing_debug_implementations)]
pub struct ZeroSizedAssertion;
#[allow(
missing_copy_implementations,
missing_debug_implementations,
non_camel_case_types
)]
pub struct a_variable;
#[allow(clippy::missing_safety_doc)]
#[inline(always)]
pub fn transmute<T, U>(e: T) -> U {
use std::mem::{self, align_of, size_of};
assert_eq!(
(size_of::<T>(), align_of::<T>()),
(size_of::<U>(), align_of::<U>())
);
let ret = unsafe { mem::transmute_copy(&e) };
mem::forget(e);
ret
}
}
pub mod traits {
#![allow(non_snake_case)]
#[cfg(nightly)]
use std::marker::Tuple;
use std::ops;
pub trait FnOnce<Args> {
type Output;
fn call_once(self, args: Args) -> Self::Output;
}
pub trait FnMut<Args>: FnOnce<Args> {
fn call_mut(&mut self, args: Args) -> Self::Output;
}
pub trait Fn<Args>: FnMut<Args> {
fn call(&self, args: Args) -> Self::Output;
}
pub trait FnOnceBox<A> {
type Output;
fn call_once_box(self: Box<Self>, args: A) -> Self::Output;
}
impl<A, F> FnOnceBox<A> for F
where
F: FnOnce<A>,
{
type Output = F::Output;
#[inline(always)]
fn call_once_box(self: Box<F>, args: A) -> F::Output {
self.call_once(args)
}
}
#[cfg(not(nightly))]
macro_rules! fn_once {
($($t:ident)*) => {
impl<T, $($t,)* O> FnOnce<($($t,)*)> for T
where
T: ops::FnOnce($($t,)*) -> O,
{
type Output = O;
#[inline(always)]
fn call_once(self, ($($t,)*): ($($t,)*)) -> Self::Output {
self($($t,)*)
}
}
fn_once!(@recurse $($t)*);
};
(@recurse $first:ident $($t:ident)*) => {
fn_once!($($t)*);
};
(@recurse) => {};
}
#[cfg(not(nightly))]
fn_once!(A B C D E F G H I J K L);
#[cfg(nightly)]
impl<T, Args: Tuple> FnOnce<Args> for T
where
T: ops::FnOnce<Args>,
{
type Output = T::Output;
#[inline(always)]
fn call_once(self, args: Args) -> Self::Output {
self.call_once(args)
}
}
#[cfg(not(nightly))]
macro_rules! fn_mut {
($($t:ident)*) => {
impl<T, $($t,)* O> FnMut<($($t,)*)> for T
where
T: ops::FnMut($($t,)*) -> O,
{
#[inline(always)]
fn call_mut(&mut self, ($($t,)*): ($($t,)*)) -> Self::Output {
self($($t,)*)
}
}
fn_mut!(@recurse $($t)*);
};
(@recurse $first:ident $($t:ident)*) => {
fn_mut!($($t)*);
};
(@recurse) => {};
}
#[cfg(not(nightly))]
fn_mut!(A B C D E F G H I J K L);
#[cfg(nightly)]
impl<T, Args: Tuple> FnMut<Args> for T
where
T: ops::FnMut<Args>,
{
#[inline(always)]
fn call_mut(&mut self, args: Args) -> Self::Output {
self.call_mut(args)
}
}
#[cfg(not(nightly))]
macro_rules! fn_ref {
($($t:ident)*) => {
impl<T, $($t,)* O> Fn<($($t,)*)> for T
where
T: ops::Fn($($t,)*) -> O,
{
#[inline(always)]
fn call(&self, ($($t,)*): ($($t,)*)) -> Self::Output {
self($($t,)*)
}
}
fn_ref!(@recurse $($t)*);
};
(@recurse $first:ident $($t:ident)*) => {
fn_ref!($($t)*);
};
(@recurse) => {};
}
#[cfg(not(nightly))]
fn_ref!(A B C D E F G H I J K L);
#[cfg(nightly)]
impl<T, Args: Tuple> Fn<Args> for T
where
T: ops::Fn<Args>,
{
#[inline(always)]
fn call(&self, args: Args) -> Self::Output {
self.call(args)
}
}
}
pub mod structs {
use serde::{Deserialize, Serialize};
use std::fmt::{self, Debug};
#[cfg(nightly)]
use std::marker::Tuple;
use super::internal;
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
pub struct FnOnce<F> {
f: F,
}
impl<F> FnOnce<F> {
#[doc(hidden)]
#[inline(always)]
pub fn internal_new<I>(f: F) -> Self
where
F: internal::FnOnce<I>,
{
Self { f }
}
}
#[cfg(not(nightly))]
impl<F, I> super::traits::FnOnce<I> for FnOnce<F>
where
F: internal::FnOnce<I>,
{
type Output = F::Output;
#[inline(always)]
fn call_once(self, args: I) -> Self::Output {
self.f.call_once(args)
}
}
#[cfg(nightly)]
impl<F, I: Tuple> std::ops::FnOnce<I> for FnOnce<F>
where
F: internal::FnOnce<I>,
{
type Output = F::Output;
#[inline(always)]
extern "rust-call" fn call_once(self, args: I) -> Self::Output {
self.f.call_once(args)
}
}
impl<F> Debug for FnOnce<F>
where
F: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.f, f)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
pub struct FnMut<F> {
f: F,
}
impl<F> FnMut<F> {
#[doc(hidden)]
#[inline(always)]
pub fn internal_new<I>(f: F) -> Self
where
F: internal::FnMut<I>,
{
Self { f }
}
}
#[cfg(not(nightly))]
impl<F, I> super::traits::FnOnce<I> for FnMut<F>
where
F: internal::FnOnce<I>,
{
type Output = F::Output;
#[inline(always)]
fn call_once(self, args: I) -> Self::Output {
self.f.call_once(args)
}
}
#[cfg(nightly)]
impl<F, I: Tuple> std::ops::FnOnce<I> for FnMut<F>
where
F: internal::FnOnce<I>,
{
type Output = F::Output;
#[inline(always)]
extern "rust-call" fn call_once(self, args: I) -> Self::Output {
self.f.call_once(args)
}
}
#[cfg(not(nightly))]
impl<F, I> super::traits::FnMut<I> for FnMut<F>
where
F: internal::FnMut<I>,
{
#[inline(always)]
fn call_mut(&mut self, args: I) -> Self::Output {
self.f.call_mut(args)
}
}
#[cfg(nightly)]
impl<F, I: Tuple> std::ops::FnMut<I> for FnMut<F>
where
F: internal::FnMut<I>,
{
#[inline(always)]
extern "rust-call" fn call_mut(&mut self, args: I) -> Self::Output {
self.f.call_mut(args)
}
}
impl<F> Debug for FnMut<F>
where
F: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.f, f)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Fn<F> {
f: F,
}
impl<F> Fn<F> {
#[doc(hidden)]
#[inline(always)]
pub fn internal_new<I>(f: F) -> Self
where
F: internal::Fn<I>,
{
Self { f }
}
}
#[cfg(not(nightly))]
impl<F, I> super::traits::FnOnce<I> for Fn<F>
where
F: internal::FnOnce<I>,
{
type Output = F::Output;
#[inline(always)]
fn call_once(self, args: I) -> Self::Output {
self.f.call_once(args)
}
}
#[cfg(nightly)]
impl<F, I: Tuple> std::ops::FnOnce<I> for Fn<F>
where
F: internal::FnOnce<I>,
{
type Output = F::Output;
#[inline(always)]
extern "rust-call" fn call_once(self, args: I) -> Self::Output {
self.f.call_once(args)
}
}
#[cfg(not(nightly))]
impl<F, I> super::traits::FnMut<I> for Fn<F>
where
F: internal::FnMut<I>,
{
#[inline(always)]
fn call_mut(&mut self, args: I) -> Self::Output {
self.f.call_mut(args)
}
}
#[cfg(nightly)]
impl<F, I: Tuple> std::ops::FnMut<I> for Fn<F>
where
F: internal::FnMut<I>,
{
#[inline(always)]
extern "rust-call" fn call_mut(&mut self, args: I) -> Self::Output {
self.f.call_mut(args)
}
}
#[cfg(not(nightly))]
impl<F, I> super::traits::Fn<I> for Fn<F>
where
F: internal::Fn<I>,
{
#[inline(always)]
fn call(&self, args: I) -> Self::Output {
self.f.call(args)
}
}
#[cfg(nightly)]
impl<F, I: Tuple> std::ops::Fn<I> for Fn<F>
where
F: internal::Fn<I>,
{
#[inline(always)]
extern "rust-call" fn call(&self, args: I) -> Self::Output {
self.f.call(args)
}
}
impl<F> Debug for Fn<F>
where
F: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.f, f)
}
}
}