use {
fp_macros::{
Apply,
impl_kind,
trait_kind,
},
std::fmt::Display,
};
trait_kind!(
type Of<T>;
);
struct Wrapper<T>(T);
struct WrapperBrand;
impl_kind! {
impl for WrapperBrand {
type Of<T> = Wrapper<T>;
}
}
#[test]
fn test_wrapper_kind() {
let w = Wrapper(42);
assert_eq!(w.0, 42);
}
#[test]
fn test_apply_macro_simple() {
type Applied = Apply!(<WrapperBrand as Kind!( type Of<T>; )>::Of<i32>);
let w: Applied = Wrapper(100);
assert_eq!(w.0, 100);
}
trait_kind!(
type Of<'a, T: 'a>;
);
struct RefWrapper<'a, T: 'a>(&'a T);
struct RefWrapperBrand;
impl_kind! {
impl for RefWrapperBrand {
type Of<'a, T: 'a> = RefWrapper<'a, T>;
}
}
#[test]
fn test_ref_wrapper_kind() {
let val = 42;
let w = RefWrapper(&val);
assert_eq!(*w.0, 42);
}
#[test]
fn test_apply_macro_with_lifetime() {
type Applied<'a> = Apply!(<RefWrapperBrand as Kind!( type Of<'a, T: 'a>; )>::Of<'a, i32>);
let val = 100;
let w: Applied = RefWrapper(&val);
assert_eq!(*w.0, 100);
}
trait_kind!(
type Of<T: Display>;
);
struct DisplayWrapper<T: Display>(T);
struct DisplayWrapperBrand;
impl_kind! {
impl for DisplayWrapperBrand {
type Of<T: Display> = DisplayWrapper<T>;
}
}
#[test]
fn test_bounded_kind() {
type Applied = Apply!(<DisplayWrapperBrand as Kind!( type Of<T: Display>; )>::Of<String>);
let w: Applied = DisplayWrapper("hello".to_string());
assert_eq!(w.0, "hello");
}
trait_kind!(
type Of<T: Clone>: Clone;
);
#[derive(Clone)]
struct CloneWrapper<T>(T);
struct CloneWrapperBrand;
impl_kind! {
impl for CloneWrapperBrand {
type Of<T: Clone>: Clone = CloneWrapper<T>;
}
}
#[test]
fn test_output_bounded_kind() {
let _ = CloneWrapper(10);
}
#[test]
fn test_apply_output_bounded() {
type Applied = Apply!(<CloneWrapperBrand as Kind!( type Of<T: Clone>: Clone; )>::Of<i32>);
let w: Applied = CloneWrapper(10);
let _ = w.clone();
}
#[test]
fn test_apply_explicit_kind() {
trait MyExplicitKind {
type Of<T>;
}
struct ExplicitWrapper<T>(T);
struct ExplicitBrand;
impl MyExplicitKind for ExplicitBrand {
type Of<T> = ExplicitWrapper<T>;
}
type Applied = <ExplicitBrand as MyExplicitKind>::Of<i32>;
let w: Applied = ExplicitWrapper(99);
assert_eq!(w.0, 99);
}