use batch_impl::{batch_impl, batch_impl_only};
use std::collections::HashMap;
#[batch_impl(HashMap u32 String)]
trait DashMapGen {}
#[test]
fn dash_op() {
fn check<T: DashMapGen>(_: &T) {}
check(&HashMap::<u32, String>::new());
}
struct SpaceBox<T>(T);
struct Pair<T, U>(T, U);
#[batch_impl(SpaceMark u8 { fn tag(&self) -> &'static str { "u8" } })]
trait SpaceMark {
fn tag(&self) -> &'static str;
}
#[batch_impl(SpaceGen<u16> u16 { fn tag(&self) -> &'static str { "u16" } })]
trait SpaceGen<T> {
fn tag(&self) -> &'static str;
}
#[batch_impl(SpaceBox <u8> { fn bits(&self) -> u32 { 8 } })]
trait SpaceType {
fn bits(&self) -> u32;
}
#[batch_impl(Pair u8 u16 { fn pair(&self) -> (u8, u16) { (self.0, self.1) } })]
trait SpaceAcc {
fn pair(&self) -> (u8, u16);
}
#[batch_impl(fn(u32) String { fn call(&self, x: u32) -> String { format!("{}", x) } })]
trait SpaceFnRet {
fn call(&self, x: u32) -> String;
}
#[batch_impl(fn(u8) -> SpaceBox u8 { fn w(&self) -> SpaceBox<u8> { SpaceBox(1u8) } })]
trait SpaceFnRetBox {
fn w(&self) -> SpaceBox<u8>;
}
#[test]
fn space_apply_semantics() {
fn check<T: SpaceMark>(t: &T) {
assert_eq!(t.tag(), "u8");
}
check(&8u8);
fn check_t<T: SpaceGen<u16>>(t: &T) {
assert_eq!(t.tag(), "u16");
}
check_t(&16u16);
fn check2<T: SpaceType>(t: &T) {
assert_eq!(t.bits(), 8);
}
check2(&SpaceBox(8u8));
fn check3<T: SpaceAcc>(t: &T) {
assert_eq!(t.pair(), (1u8, 2u16));
}
check3(&Pair(1u8, 2u16));
fn check4<T: SpaceFnRet>(f: &T) {
assert_eq!(f.call(7), "7");
}
let f: fn(u32) -> String = |x| format!("{}", x);
check4(&f);
fn check5<T: SpaceFnRetBox>(f: &T) {
assert_eq!(f.w().0, 1u8);
}
let g: fn(u8) -> SpaceBox<u8> = |x| SpaceBox(x);
check5(&g);
}
#[batch_impl(<T> Describe<T> [Vec<T>, <U> HashMap<T, U>] {
fn describe(&self) -> String { format!("len={}", self.len()) }
})]
trait Describe<T> {
fn describe(&self) -> String;
}
#[test]
fn nested_generic_list() {
let v: Vec<i32> = vec![1, 2, 3];
assert_eq!(v.describe(), "len=3");
let m: HashMap<i32, String> = HashMap::from([(1, String::from("a"))]);
assert_eq!(m.describe(), "len=1");
}
trait PairAB<A, B> {
fn pair(&self) -> (A, B);
}
#[batch_impl_only(
<A> <B> PairAB<A, B> (A, B) where{ A: Clone, B: Clone }
{ fn pair(&self) -> (A, B) { (self.0.clone(), self.1.clone()) } }
)]
trait PairAB<A, B> {
fn pair(&self) -> (A, B);
}
#[test]
fn nested_generics_merge() {
let p = (1u32, String::from("x"));
assert_eq!(p.pair(), (1u32, String::from("x")));
}
#[rustfmt::skip]
#[batch_impl(usize, isize,)]
trait TrailingCommaOk {}
#[batch_impl(())]
trait EmptyTupleOk {}
#[batch_impl(usize, isize)]
trait NoTrailingIssue {}
#[test]
fn strictness_legal_forms() {
fn check<T: TrailingCommaOk>() {}
check::<usize>();
check::<isize>();
fn check2<T: EmptyTupleOk>() {}
check2::<()>();
fn check3<T: NoTrailingIssue>() {}
check3::<isize>();
}