use super::{argument::ProvideArgument, *};
pub trait Tuple: sealed::Sealed {}
pub trait IsCallable {
fn accept_anything(self) -> accept_anything::AcceptAnything<Self>
where
Self: Sized + Callable<()>,
{
accept_anything::AcceptAnything(self)
}
fn provide_last_argument<
A: ProvideArgument<
ProvideArgumentType = <Self::FixedArgumentTypes as argument::ArgumentTypes>::Last,
>,
>(
self,
last_argument: A,
) -> super::argument::LastArgumentProvided<Self, A>
where
Self: Sized + CallableWithFixedArguments,
{
super::argument::LastArgumentProvided {
f: self,
last_argument,
}
}
fn provide_first_argument<
A: ProvideArgument<
ProvideArgumentType = <Self::FixedArgumentTypes as argument::ArgumentTypes>::First,
>,
>(
self,
first_argument: A,
) -> super::argument::FirstArgumentProvided<Self, A>
where
Self: Sized + CallableWithFixedArguments,
{
super::argument::FirstArgumentProvided {
f: self,
first_argument,
}
}
fn provide_last_argument_refed<T>(
self,
last_argument: T,
) -> super::argument::LastArgumentProvided<Self, argument::Refed<T>>
where
Self: Sized + CallableWithFixedArguments,
Self::FixedArgumentTypes: argument::ArgumentTypes<Last = argument::ByRef<T>>,
{
super::argument::LastArgumentProvided {
f: self,
last_argument: argument::Refed(last_argument),
}
}
fn provide_first_argument_refed<T>(
self,
first_argument: T,
) -> super::argument::FirstArgumentProvided<Self, argument::Refed<T>>
where
Self: Sized + CallableWithFixedArguments,
Self::FixedArgumentTypes: argument::ArgumentTypes<First = argument::ByRef<T>>,
{
super::argument::FirstArgumentProvided {
f: self,
first_argument: argument::Refed(first_argument),
}
}
fn provide_first_argument_copied<T: Copy>(
self,
first_argument: T,
) -> super::argument::FirstArgumentProvided<Self, argument::Copied<T>>
where
Self: Sized + CallableWithFixedArguments,
Self::FixedArgumentTypes: argument::ArgumentTypes<First = argument::Value<T>>,
{
self.provide_first_argument(argument::Copied(first_argument))
}
fn provide_last_argument_copied<T: Copy>(
self,
last_argument: T,
) -> super::argument::LastArgumentProvided<Self, argument::Copied<T>>
where
Self: Sized + CallableWithFixedArguments,
Self::FixedArgumentTypes: argument::ArgumentTypes<Last = argument::Value<T>>,
{
super::argument::LastArgumentProvided {
f: self,
last_argument: argument::Copied(last_argument),
}
}
fn provide_last_argument_cloned<T: Clone>(
self,
last_argument: T,
) -> super::argument::LastArgumentProvided<Self, argument::Cloned<T>>
where
Self: Sized + CallableWithFixedArguments,
Self::FixedArgumentTypes: argument::ArgumentTypes<Last = argument::Value<T>>,
{
super::argument::LastArgumentProvided {
f: self,
last_argument: argument::Cloned(last_argument),
}
}
fn provide_first_argument_cloned<T: Clone>(
self,
first_argument: T,
) -> super::argument::FirstArgumentProvided<Self, argument::Cloned<T>>
where
Self: Sized + CallableWithFixedArguments,
Self::FixedArgumentTypes: argument::ArgumentTypes<First = argument::Value<T>>,
{
super::argument::FirstArgumentProvided {
f: self,
first_argument: argument::Cloned(first_argument),
}
}
fn provide_first_argument_with<F: Callable<()>>(
self,
get_first_argument: F,
) -> super::argument::FirstArgumentProvided<Self, argument::With<F>>
where
Self: Sized + CallableWithFixedArguments,
Self::FixedArgumentTypes:
argument::ArgumentTypes<First = argument::Value<<F as Callable<()>>::Output>>,
{
super::argument::FirstArgumentProvided {
f: self,
first_argument: argument::With(get_first_argument),
}
}
fn provide_last_argument_with<F: Callable<()>>(
self,
get_first_argument: F,
) -> super::argument::LastArgumentProvided<Self, argument::With<F>>
where
Self: Sized + CallableWithFixedArguments,
Self::FixedArgumentTypes:
argument::ArgumentTypes<Last = argument::Value<<F as Callable<()>>::Output>>,
{
super::argument::LastArgumentProvided {
f: self,
last_argument: argument::With(get_first_argument),
}
}
}
pub trait Callable<Args: Tuple>: crate::IsCallable {
type Output;
fn call_fn(&self, args: Args) -> Self::Output;
}
pub trait CallableOne<IN>: Callable<(IN,)> {
fn emit(&self, input: IN) -> Self::Output {
self.call_fn((input,))
}
fn chain<F: CallableOne<Self::Output>>(self, f: F) -> chain::Chain<Self, F>
where
Self: Sized,
{
chain::Chain(self, f)
}
fn reform<NewInput, F: CallableOne<NewInput, Output = IN>>(self, f: F) -> chain::Chain<F, Self>
where
Self: Sized,
{
f.chain(self)
}
fn reform_ref<NewInput: ?Sized, F: for<'i> CallableOne<&'i NewInput, Output = IN>>(
self,
f: F,
) -> chain::Chain<F, Self>
where
Self: Sized,
{
chain::Chain(f, self)
}
fn reform_mut<NewInput: ?Sized, F: for<'input> CallableOne<&'input mut NewInput, Output = IN>>(
self,
f: F,
) -> chain::Chain<F, Self>
where
Self: Sized,
{
chain::Chain(f, self)
}
}
impl<A1, F: Callable<(A1,)>> crate::CallableOne<A1> for F {}
pub trait CallableWithFixedArguments:
IsCallable
+ for<'a> crate::Callable<super::argument::ArgumentsOfTypes<'a, Self::FixedArgumentTypes>>
{
type FixedArgumentTypes: argument::ArgumentTypes;
fn call_with_prepended_args<'first: 'out, 'args: 'out, 'out>(
&self,
first: super::argument::ArgumentOfType<
'first,
<Self::FixedArgumentTypes as argument::ArgumentTypes>::First,
>,
args: super::argument::ArgumentsOfTypes<
'args,
<Self::FixedArgumentTypes as argument::ArgumentTypes>::FirstTrimmed,
>,
) -> <Self as Callable<super::argument::ArgumentsOfTypes<'out, Self::FixedArgumentTypes>>>::Output
{
let first = <<Self::FixedArgumentTypes as argument::ArgumentTypes>::First as argument::ArgumentType>::re_borrow(first);
let args = <<Self::FixedArgumentTypes as argument::ArgumentTypes>::FirstTrimmed as argument::ArgumentTypes>::re_borrow(args);
self.call_fn(
<Self::FixedArgumentTypes as argument::ArgumentTypes>::from_prepended(first, args),
)
}
fn call_with_appended_args<'last: 'out, 'args: 'out, 'out>(
&self,
args: super::argument::ArgumentsOfTypes<
'args,
<Self::FixedArgumentTypes as argument::ArgumentTypes>::LastTrimmed,
>,
last: super::argument::ArgumentOfType<
'last,
<Self::FixedArgumentTypes as argument::ArgumentTypes>::Last,
>,
) -> <Self as Callable<super::argument::ArgumentsOfTypes<'out, Self::FixedArgumentTypes>>>::Output
{
let args = <<Self::FixedArgumentTypes as argument::ArgumentTypes>::LastTrimmed as argument::ArgumentTypes>::re_borrow(args);
let last = <<Self::FixedArgumentTypes as argument::ArgumentTypes>::Last as argument::ArgumentType>::re_borrow(last);
self.call_fn(
<Self::FixedArgumentTypes as argument::ArgumentTypes>::from_appended(args, last),
)
}
}