typewit::type_fn

Trait RevTypeFn

Source
pub trait RevTypeFn<Ret: ?Sized>: TypeFn<Self::Arg, Output = Ret> {
    type Arg: ?Sized;
}
Expand description

The inverse of TypeFn, for getting the argument of a TypeFn from its return value.

§Properties

These are properties about RevTypeFn that users can rely on.

For any given F: RevTypeFn<R> + RevTypeFn<O> these hold:

  1. If R == O, then UncallFn<F, R> == UncallFn<F, O>

  2. If R != O, then UncallFn<F, R> != UncallFn<F, O>

Disclaimer: this trait does not by itself ensure that a function is injective, since RevTypeFn<Ret> can’t know if Self::Arg is the only argument that could produce Ret.

§Examples

§Macro-based impl

use std::ops::Range;

use typewit::{RevTypeFn, UncallFn};

let array = [3usize, 5];

// Getting the argument of `ArrayFn` from its return value
let value: UncallFn<ArrayFn<2>, [usize; 2]> = array[0];

assert_eq!(value, 3usize);

typewit::inj_type_fn!{
    struct ArrayFn<const N: usize>;
    impl<T> T => [T; N]
}

§Manual impl

use std::ops::Range;

use typewit::{CallInjFn, RevTypeFn, TypeFn, UncallFn};

let array = [3usize, 5];

// Getting the argument of `ArrayFn` from its return value
let value: UncallFn<ArrayFn<2>, [usize; 2]> = array[0];

assert_eq!(value, 3usize);

struct ArrayFn<const N: usize>;

impl<T, const N: usize> TypeFn<T> for ArrayFn<N> {
    type Output = [T; N];

    // Ensures that this impl of `TypeFn` for `ArrayFn` is injective.
    const TYPE_FN_ASSERTS: () = { let _: CallInjFn<Self, T>; };
}
impl<T, const N: usize> RevTypeFn<[T; N]> for ArrayFn<N> {
    type Arg = T;
}

§Non-injective function

As mentioned above, this trait doesn’t make a function injective.

In the example below, NonInjective isn’t injective, because it maps different arguments to the same return value:

use typewit::{CallFn, RevTypeFn, TypeFn, UncallFn};
 
let _: CallFn<NonInjective, Vec<u8>> = 3u8;
let _: CallFn<NonInjective, String> = 5u8;
 
let _: UncallFn<NonInjective, u8> = ();
 
 
struct NonInjective;
 
impl<T> TypeFn<T> for NonInjective {
    type Output = u8;
}
 
impl RevTypeFn<u8> for NonInjective {
    type Arg = ();
}

Required Associated Types§

Source

type Arg: ?Sized

The argument to this function with Ret as the return value.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<F, R: ?Sized> RevTypeFn<R> for PhantomData<F>
where F: RevTypeFn<R>,

Source§

type Arg = <F as RevTypeFn<R>>::Arg

Implementors§

Source§

impl<'a, T: 'a + ?Sized> RevTypeFn<&'a T> for GRef<'a>

Source§

type Arg = T

Source§

impl<'a, T: 'a + ?Sized> RevTypeFn<&'a mut T> for GRefMut<'a>

Source§

type Arg = T

Source§

impl<F, R: ?Sized> RevTypeFn<R> for FnRev<F>
where F: InjTypeFn<R>,

Source§

type Arg = <F as InjTypeFn<R>>::Ret

Source§

impl<F, R: ?Sized> RevTypeFn<R> for Invoke<F>
where F: RevTypeFn<R>,

Source§

type Arg = <F as RevTypeFn<R>>::Arg

Source§

impl<T: ?Sized> RevTypeFn<T> for FnIdentity

Source§

type Arg = T