type-fn 0.2.0

Allows for simpler coding of type-level logic, e.g. for type-number systems.
Documentation
use std::{any, marker::PhantomData};

use type_fn::*;

pub struct EmptyList;
pub struct ListExt<T, Next>(PhantomData<T>, PhantomData<Next>);

pub struct RemovalResult<Element, List>(PhantomData<Element>, PhantomData<List>);

type_fn! {
    pub fn AddElement<List, Element>;
    pub fn RemoveLastElement<List>;

    pub fn GetRemoved<R>;
    pub fn GetChangedList<R>;
}

type_fn_impl! {
    fn AddElement<List, Element> => ListExt<Element, List>;
    fn RemoveLastElement<List => ListExt<Element, List> | Element> => RemovalResult<Element, List>;

    fn GetRemoved<Element => RemovalResult<Element, List> | List> => Element;
    fn GetChangedList<List => RemovalResult<Element, List> | Element> => List;
}

fn main() {
    struct Hello;
    struct World;

    type MyListA = EmptyList;
    type MyListB = call!(AddElement<MyListA, World>);
    type MyListC = call!(AddElement<MyListB, Hello>);

    type RemovalA = call!(RemoveLastElement<MyListC>);
    println!("{}", any::type_name::<call!(GetRemoved<RemovalA>)>());

    type MyListD = call!(GetChangedList<RemovalA>);
    type RemovalB = call!(RemoveLastElement<MyListD>);
    println!("{}", any::type_name::<call!(GetRemoved<RemovalB>)>());
}