use batch_impl::{batch_impl, batch_trait};
#[batch_impl(
Box<u32> impl{X<u32>} impl{Y<u32>} impl{Z<u32>}
{ fn mk(x: u32) -> X<u32> { X::new(x) } }
)]
trait BndT1 {
fn mk(x: u32) -> Self;
}
#[test]
fn impl_three_templates_merge() {
assert_eq!(*<Box<u32> as BndT1>::mk(3), 3);
}
#[batch_impl(Box<u32> impl{X} impl{X} { fn mk(x: u32) -> X { Box::new(x) } })]
trait BndT2 {
fn mk(x: u32) -> Self;
}
#[test]
fn impl_redundant_identical_binding() {
assert_eq!(*<Box<u32> as BndT2>::mk(4), 4);
}
struct BndT3<T>(T);
#[batch_impl(BndT3<u8> impl{@trait<T>} { fn tag(&self) -> u32 { 3 } })]
trait BndMarker {
fn tag(&self) -> u32;
}
#[test]
fn impl_at_trait_template() {
let b = BndT3(1u8);
assert_eq!(b.tag(), 3);
}
#[batch_impl(Box<u8> impl{X} { fn tag(&self) -> u32 { 4 } })]
unsafe trait BndT4 {
fn tag(&self) -> u32;
}
unsafe impl BndT4 for u8 {
fn tag(&self) -> u32 {
4
}
}
#[test]
fn impl_unsafe_trait() {
assert_eq!(<Box<u8> as BndT4>::tag(&Box::new(1)), 4);
}
trait BtImpl {}
batch_trait!(BtImpl: i32 impl{T});
#[test]
fn impl_batch_trait() {
fn check<T: BtImpl>() {}
check::<i32>();
}
#[batch_impl(#[allow(dead_code)] Box<u8> impl{X} { fn tag(&self) -> u32 { 6 } })]
trait BndT6 {
fn tag(&self) -> u32;
}
#[test]
fn impl_with_attribute() {
assert_eq!(<Box<u8> as BndT6>::tag(&Box::new(1)), 6);
}
#[batch_impl(Box<u8> impl{X} #fill(@all_methods){7})]
trait ComboFill {
fn a(&self) -> u32;
fn b(&self) -> u32;
}
#[test]
fn impl_with_fill_directive() {
let b = Box::new(1u8);
assert_eq!(b.a(), 7);
assert_eq!(b.b(), 7);
}
#[batch_impl(()^2 impl{(A, B)} where{@0: Clone} { fn n(&self) -> usize { 2 } })]
trait ComboAtN {
fn n(&self) -> usize;
}
#[test]
fn impl_with_at_n_where() {
let t = (1u8, 2u16);
assert_eq!(t.n(), 2);
}
#[batch_impl(u8 { fn tag9(&self) -> u32 { 9 } })]
#[batch_impl(#blanket(tag9){Box} impl{X})]
trait ComboBlanket {
fn tag9(&self) -> u32;
}
#[test]
fn impl_with_blanket() {
assert_eq!(Box::new(5u8).tag9(), 9);
}